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
23           Mason provides reasonable default behavior under mod_perl, so using
24           Mason can be as simple as adding two directives to your Apache
25           configuration file.  Throughout this document, we will assume that
26           your Apache configuration file is called httpd.conf.  By adding
27           more configuration parameters to this file you can implement more
28           complex behaviors.
29
30       •   Advanced
31
32           If the basic method does not provide enough flexibility for you,
33           you can wrap Mason in a custom mod_perl handler.  The wrapper code
34           you write can create its own Mason objects, or it can take
35           advantage of httpd.conf configuration parameters and let Mason
36           create the objects it needs by itself.
37
38       We recommend that you start with the basic method and work your way
39       forward as the need for flexibility arises.
40
41       Mason is very flexible, and you can replace parts of it by creating
42       your own classes.  This documentation assumes that you are simply using
43       the classes provided in the Mason distribution.  Subclassing is covered
44       in the Subclassing document.  The two topics are orthogonal, as you can
45       mix the configuration techniques discussed here with your own custom
46       subclasses.
47

BASIC CONFIGURATION VIA httpd.conf DIRECTIVES

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

GENERAL SERVER CONFIGURATION

184   Component Root
185       The component root (comp_root) marks the top of your component
186       hierarchy.  When running Mason with the ApacheHandler or CGIHandler
187       modules, this defaults to your document root.
188
189       The component root defines how component paths are translated into real
190       file paths. If your component root is /usr/local/httpd/docs, a
191       component path of /products/index.html translates to the file
192       /usr/local/httpd/docs/products/index.html.
193
194       One cannot call a component outside the component root. If Apache
195       passes a file through Mason that is outside the component root (say, as
196       the result of an Alias) you will get a 404 and a warning in the logs.
197
198       You may also specify multiple component roots in the spirit of Perl's
199       @INC. Each root is assigned a key that identifies the root
200       mnemonically. For example, in httpd.conf:
201
202           PerlAddVar  MasonCompRoot  "private => /usr/home/joe/comps"
203           PerlAddVar  MasonCompRoot  "main => /usr/local/www/htdocs"
204
205       This specifies two component roots, a main component tree and a private
206       tree which overrides certain components.  The order is respected ala
207       @INC, so private is searched first and main second.
208
209       The component root keys must be unique in a case-insensitive
210       comparison. The keys are used in several ways. They help to distinguish
211       component caches and object files between different component roots,
212       and they appear in the "title()" of a component.
213
214   Data Directory
215       The data directory (data_dir) is a writable directory that Mason uses
216       for various features and optimizations. By default, it is a directory
217       called "mason" under your Apache server root.  Because Mason will not
218       use a default data directory under a top-level directory, you will need
219       to change this on certain systems that assign a high-level server root
220       such as /usr or /etc.
221
222       Mason will create the directory on startup, if necessary, and set its
223       permissions according to the web server User/Group.
224
225   External Modules
226       Components will often need access to external Perl modules. There are
227       several ways to load them.
228
229       •   The httpd PerlModule directive:
230
231               PerlModule CGI
232               PerlModule LWP
233
234       •   In the "<%once>" section of the component(s) that use the module.
235
236               <%once>
237               use CGI ':standard';
238               use LWP;
239               </%once>
240
241       Each method has its own trade-offs:
242
243       The first method ensures that the module will be loaded by the Apache
244       parent process at startup time, saving time and memory.  The second
245       method, in contrast, will cause the modules to be loaded by each server
246       child. On the other hand this could save memory if the component and
247       module are rarely used. See the mod_perl guide's tuning section and
248       Vivek Khera's mod_perl tuning guide for more details on this issue.
249
250       The second method uses the modules from inside the package used by
251       components ("HTML::Mason::Commands"), meaning that exported method
252       names and other symbols will be usable from components.  The first
253       method, in contrast, will import symbols into the "main" package. The
254       significance of this depends on whether the modules export symbols and
255       whether you want to use them from components.
256
257       If you want to preload the modules in your httpd.conf file, and still
258       have them export symbols into the "HTML::Mason::Commands" namespace,
259       you can do this:
260
261         <Perl>
262         { package HTML::Mason::Commands;
263           use CGI;
264           use LWP;
265         }
266         </Perl>
267
268       A Perl section will also work for including local library paths:
269
270         <Perl>
271         use lib '/path/to/local/lib';
272         </Perl>
273
274   Allowing Directory Requests
275       By default Mason will decline requests for directories, leaving Apache
276       to serve up a directory index or a FORBIDDEN as appropriate.
277       Unfortunately this rule applies even if there is a dhandler in the
278       directory: /foo/bar/dhandler does not get a chance to handle a request
279       for /foo/bar/.
280
281       If you would like Mason to handle directory requests, set decline_dirs
282       to 0.  The dhandler that catches a directory request is responsible for
283       setting a reasonable content type via "$r->content_type()".
284
285   Configuring Virtual Sites
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
364       content handler that wraps around Mason and provides basically
365       unlimited flexibility when handling requests.  In this section, we show
366       some basic wrappers and re-implement some of the functionality
367       previously discussed, such as declining image requests and protecting
368       private components.
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
372       mechanism.  This wrapper generally consists of two parts.  The
373       initialization portion, run at server startup, will load any needed
374       modules and create objects.  The other portion is the "handler()"
375       subroutine, which handles web page requests.
376
377   Writing a Wrapper
378       To create a wrapper, you simply need to define a "handler()" subroutine
379       in the package of your choice, and tell mod_perl to use it as a content
380       handler.  The file that defines the "handler()" subroutine can be a
381       module, or you can simply load a simple file that contains this
382       subroutine definition.  The latter solution was, for a long time, the
383       only way to configure Mason, and the file used was traditionally called
384       handler.pl.
385
386       Nowadays, we recommend that you create a custom module in the
387       appropriate namespace and define your "handler()" subroutine there.
388       The advantage to this approach is that it uses well-known techniques
389       for creating and installing modules, but it does require a bit more
390       work than simply dropping a script file into the Apache configuration
391       directory.  But because the process is better defined, it may "feel"
392       more solid to some folks than the script approach.
393
394       The eg/ directory of the Mason distribution contains a couple sample
395       modules that define "handler()" subroutines.  Let's assume that your
396       module, like the example, defines a "handler()" in the package
397       "MyApp::Mason".  In this case, your Apache configuration would look
398       like this:
399
400         PerlModule  MyApp::Mason
401
402         <LocationMatch ...>
403           SetHandler   perl-script
404           PerlHandler  MyApp::Mason
405         </LocationMatch>
406
407       You may still see references to a handler.pl file in the Mason users
408       list archives, as well as the FAQ.  These references will generally be
409       applicable to any custom code wrapping Mason.
410
411       Wrappers and PerlSetVar-style configuration
412
413       Sometimes people attempt to write a wrapper and configure Mason with
414       "PerlSetVar" directives in their Apache configuration file.  This does
415       not work.  When you give mod_perl this configuration:
416
417         PerlHandler HTML::Mason::ApacheHandler
418
419       it will dispatch directly to the
420       "HTML::Mason::ApacheHandler->handler()" method, without ever executing
421       your wrapper code.  However, you can mix the two methods.  See Mixing
422       httpd.conf Configuration with a Wrapper
423
424   Wrapping with a <Perl> block
425       You can also put your wrapper code in a "<Perl>" block as part of your
426       httpd.conf file.  The result is no different than loading a file via
427       the "PerlRequire" directive.
428
429   The Wrapper Code
430       Regardless of how you load your wrapper code, it will always work the
431       same way.  The "handler()" subroutine should expect to receive the
432       Apache request object representing the current request.  This request
433       object is used by the ApacheHandler module to determine what component
434       is being called.
435
436       Let's look at the guts of some wrapper code.  Here's a first version:
437
438         package MyApp::Mason;
439
440         use strict;
441         use HTML::Mason::ApacheHandler;
442
443         my $ah =
444             HTML::Mason::ApacheHandler->new
445                 ( comp_root => '/path/to/comp/root',
446                   data_dir  => '/path/to/data/dir' );
447
448         sub handler {
449             my ($r) = @_;
450
451             return $ah->handle_request($r);
452         }
453
454       This wrapper is fully functional, but it doesn't actually do anything
455       you couldn't do more easily by configuring Mason via the httpd.conf
456       file.  However, it does serve as a good skeleton to which additional
457       functionality can easily be added.
458
459   External Modules Revisited
460       Since you are loading an arbitrary piece of code to define your
461       wrapper, you can easily load other modules needed for your application
462       at the same time.  For example, you might simple add these lines to the
463       wrapper code above:
464
465         {
466             package HTML::Mason::Commands;
467
468             use MIME::Base64;
469         }
470
471       Explicitly setting the package to "HTML::Mason::Commands" makes sure
472       that any symbols that the loaded modules export (constants,
473       subroutines, etc.) get exported into the namespace under which
474       components run.  Of course, if you've changed the component namespace,
475       make sure to change the package name here as well.
476
477       Alternatively, you might consider creating a separate piece of code to
478       load the modules you need.  For example, you might create a module
479       called "MyApp::MasonInit":
480
481         {
482             package HTML::Mason::Commands;
483
484             use Apache::Constants qw(:common);
485             use Apache::URI;
486             use File::Temp;
487         }
488
489         1;
490
491       This can be loaded via a "PerlModule" directive in the httpd.conf file,
492       or in the wrapper code itself via "use".
493
494       Example: Controlling access with component attributes
495
496       An example of something you can only do with wrapper code is deciding
497       at run-time whether a component can be accessed at the top-level based
498       on a complex property of the component.  For example, here's a piece of
499       code that uses the current user and a component's "access_level"
500       attribute to control access:
501
502         sub handler {
503             my ($r) = @_;
504
505             my $req = $ah->prepare_request($r);
506
507             my $comp = $req->request_comp;
508
509             # this is done via magic hand-waving ...
510             my $user = get_user_from_cookie();
511
512             # remember, attributes are inherited so this could come from a
513             # component higher up the inheritance chain
514             my $required_access = $comp->attr('access_level');
515
516             return NOT_FOUND
517                 if $user->access_level < $required_access;
518
519             return $req->exec;
520         }
521
522   Wrappers with Virtual Hosts
523       If you had several virtual hosts, each of which had a separate
524       component root, you'd need to create a separate ApacheHandler object
525       for each host, one for each host.  Here's some sample code for that:
526
527           my %ah;
528           foreach my $site ( qw( site1 site2 site3 ) ) {
529               $ah{$site} =
530                   HTML::Mason::ApacheHandler->new
531                       ( comp_root => "/usr/local/www/$site",
532                         data_dir => "/usr/local/mason/$site" );
533           }
534
535           sub handler {
536               my ($r) = @_;
537
538               my $site = $r->dir_config('SiteName');
539
540               return DECLINED unless exists $ah{$site};
541
542               return $ah{$site}->handle_request($r);
543           }
544
545       This code assumes that you set the "SiteName" variable via a
546       "PerlSetVar" directive in each "VirtualHost" block, like this:
547
548         <VirtualHost site1.example.com>
549           PerlSetVar  SiteName  site1
550
551           <LocationMatch ...>
552             SetHandler   perl-script
553             PerlHandler  MyApp::Mason
554           </LocationMatch>
555         </VirtualHost>
556
557       Creating apachehandler objects on the fly
558
559       You might also consider creating ApacheHandler objects on the fly, like
560       this:
561
562           my %ah;
563           sub handler {
564               my ($r) = @_;
565               my $site = $r->dir_config('SiteName');
566
567               return DECLINED unless $site;
568
569               unless exists($ah{$site}) {
570                   $ah{$site} = HTML::Mason::ApacheHandler->new( ... );
571               }
572
573               $ah{$site}->handle_request($r);
574           }
575
576       This is more flexible but you lose the memory savings of creating all
577       your objects during server startup.
578
579       Other uses for a wrapper
580
581       If you have some code which must always run after a request, then the
582       only way to guarantee that this happens is to wrap the
583       "$ah->handle_request()" call in an "eval {}" block, and then run the
584       needed code after the request returns.  You can then handle errors
585       however you like.
586
587   Mixing httpd.conf Configuration with a Wrapper
588       You can take advantage of Mason's httpd.conf configuration system while
589       at the same time providing your own wrapper code.  The key to doing
590       this is not creating your own ApacheHandler object.  Instead, you call
591       the "HTML::Mason::ApacheHandler->handler()" class method from your
592       "handler()" subroutine.  Here's a complete wrapper that does this:
593
594         package MyApp::Mason;
595
596         use strict;
597         use HTML::Mason::ApacheHandler;
598
599         sub handler {
600             my ($r) = @_;
601
602             return HTML::Mason::ApacheHandler->handler($r);
603         }
604
605       The "HTML::Mason::ApacheHandler->handler" method will create an
606       ApacheHandler object based on the configuration directives it finds in
607       your httpd.conf file.  Obviously, this wrapper is again a skeleton, but
608       you could mix and match this wrapper code with any of the code shown
609       above.
610
611       Alternately you could subclass the "HTML::Mason::ApacheHandler" class,
612       and override the "handler()" method it provides.  See the Subclassing
613       documentation for more details.  Of course, you could even create a
614       subclass and write a wrapper that called it.
615

DEVELOPMENT

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

PERFORMANCE

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

ERROR REPORTING AND EXCEPTIONS

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

RUNNING OUTSIDE OF MOD_PERL

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