{
    "mode": "perldoc",
    "parameter": "HTML::Mason::Admin",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/HTML%3A%3AMason%3A%3AAdmin/json",
    "generated": "2026-06-15T14:44:09Z",
    "sections": {
        "NAME": {
            "content": "HTML::Mason::Admin - Mason Administrator's Manual\n",
            "subsections": []
        },
        "DESCRIPTION": {
            "content": "This manual is written for the sysadmin/webmaster in charge of installing, configuring, or\ntuning a Mason system. The bulk of the documentation assumes that you are using modperl. See\nRUNNING OUTSIDE OF MODPERL for more details. For more details on modperl, visit the modperl\nwebsite at http://perl.apache.org/.\n",
            "subsections": []
        },
        "SITE CONFIGURATION METHODS": {
            "content": "Mason includes a module specifically designed to integrate Mason and modperl (1 and 2),\n\"HTML::Mason::ApacheHandler\". By telling modperl to hand content requests to this module, you\ncan use Mason to generate web pages. There are two ways to configure Mason under modperl.\n\n*   Basic\n\nMason provides reasonable default behavior under modperl, so using Mason can be as simple\nas adding two directives to your Apache configuration file. Throughout this document, we\nwill assume that your Apache configuration file is called httpd.conf. By adding more\nconfiguration parameters to this file you can implement more complex behaviors.\n\n*   Advanced\n\nIf the basic method does not provide enough flexibility for you, you can wrap Mason in a\ncustom modperl handler. The wrapper code you write can create its own Mason objects, or it\ncan take advantage of httpd.conf configuration parameters and let Mason create the objects\nit needs by itself.\n\nWe recommend that you start with the basic method and work your way forward as the need for\nflexibility arises.\n\nMason is very flexible, and you can replace parts of it by creating your own classes. This\ndocumentation assumes that you are simply using the classes provided in the Mason distribution.\nSubclassing is covered in the Subclassing document. The two topics are orthogonal, as you can\nmix the configuration techniques discussed here with your own custom subclasses.\n\nBASIC CONFIGURATION VIA httpd.conf DIRECTIVES\nThe absolutely most minimal configuration looks like this:\n\nPerlModule HTML::Mason::ApacheHandler\n\n<Location />\nSetHandler   perl-script\nPerlHandler  HTML::Mason::ApacheHandler\n</Location>\n\nThis configuration tells Apache to serve all URLs through Mason (see the next section for a more\nrealistic strategy). We use the PerlModule line to tell modperl to load Mason once at startup\ntime, saving time and memory. This example does not set any Mason configuration parameters, so\nMason uses its default values.\n\nIf this is your first time installing and using Mason, we recommend that you use the above\nconfiguration in a test webserver to start with. This will let you play with Mason under\nmodperl with a minimum of fuss. Once you've gotten this working, then come back and read the\nrest of the document for further possibilities.\n",
            "subsections": [
                {
                    "name": "Controlling Access via Filename Extension",
                    "content": "As it turns out, serving every URL through Mason is a bad idea for two reasons:\n\n1.  Mason should be prevented from handling images, tarballs, and other binary files. Not only\nwill performance suffer, but binary files may inadvertently contain a Mason character\nsequence such as \"<%\". These files should be instead served by Apache's default content\nhandler.\n\n2.  Mason should be prevented from serving private (non-top-level) Mason components to users.\nFor example, if you used a utility component for performing arbitrary sql queries, you\nwouldn't want external users to be able to access it via a URL. Requests for private\ncomponents should simply result in a 404 NOTFOUND.\n\nThe easiest way to distinguish between different types of files is with filename extensions.\nWhile many naming schemes are possible, we suggest using \"normal\" extensions for top-level\ncomponents and adding an \"m\" prefix for private components. For example,\n\nTop-level       Private\n\nComponent outputs HTML    .html           .mhtml\nComponent outputs text    .txt            .mtxt\nComponent executes Perl   .pl             .mpl\n\nThis scheme minimizes the chance of confusing browsers about content type, scales well for new\nclasses of content (e.g. .js/.mjs for javascript), and makes transparent the fact that you are\nusing Mason versus some other package.\n\nHere is a configuration that enforces this naming scheme:\n\nPerlModule HTML::Mason::ApacheHandler\n\n<LocationMatch \"(\\.html|\\.txt|\\.pl)$\">\nSetHandler perl-script\nPerlHandler HTML::Mason::ApacheHandler\n</LocationMatch>\n\n<LocationMatch \"(\\.m(html|txt|pl)|dhandler|autohandler)$\">\nSetHandler perl-script\nPerlInitHandler Apache::Constants::NOTFOUND\n</LocationMatch>\n\nThe first block causes URLs ending in .html, .txt, or .pl to be served through Mason. The second\nblock causes requests to private components to return 404 NOTFOUND, preventing unscrupulous\nusers from even knowing which private components exist. Any other file extensions (e.g. .gif,\n.tgz) will be served by Apache's default content handler.\n\nYou might prefer \"FilesMatch\" to \"LocationMatch\". However, be aware that \"LocationMatch\" will\nwork best in conjunction with Mason's dhandlers.\n"
                },
                {
                    "name": "Configuration Parameters",
                    "content": "Mason allows you to flexibly configure its behavior via httpd.conf configuration parameters.\n\nThese configuration parameters are set via modperl's \"PerlSetVar\" and \"PerlAddVar\" directives.\nThough these parameters are all strings in your httpd.conf file, Mason treats different\ndirectives as containing different types of values:\n\n*   string\n\nThe variable's value is simply taken literally and used. The string should be surrounded by\nquotes if the it contains whitespace. The quotes will be automatically removed by Apache\nbefore Mason sees the variable.\n\n*   boolean\n\nThe variable's value is used as a boolean, and is subject to Perl's rules on\ntruth/falseness. It is recommended that you use 0 (false) or 1 (true) for these arguments.\n\n*   code\n\nThe string is treated as a piece of code and \"eval\"'ed. This is used for parameters that\nexpect subroutine references. For example, an anonymous subroutine might look like:\n\nPerlSetVar  MasonOutMode  \"sub { ... }\"\n\nA named subroutine reference would look like this:\n\nPerlSetVar  MasonOutMode  \"\\&Some::Module::handleoutput\"\n\n*   list\n\nTo set a list parameter, use \"PerlAddVar\" for the values, like this:\n\nPerlAddVar  MasonPreloads  /foo/bar/baz.comp\nPerlAddVar  MasonPreloads  /foo/bar/quux.comp\n\n*   hashlist\n\nJust like a list parameter, use \"PerlAddVar\" for the values. However, in the case of a\nhashlist, each element should be a key/value pair separated by \"=>\":\n\nPerlAddVar  MasonDataCacheDefaults  \"cacheclass => MemoryCache\"\nPerlAddVar  MasonDataCacheDefaults  \"namespace => foo\"\n\nTake note that the right hand side of the each pair should *not* be quoted.\n\nSee HTML::Mason::Params for a full list of parameters, and their associated types.\n"
                }
            ]
        },
        "GENERAL SERVER CONFIGURATION": {
            "content": "",
            "subsections": [
                {
                    "name": "Component Root",
                    "content": "The component root (comproot) marks the top of your component hierarchy. When running Mason\nwith the ApacheHandler or CGIHandler modules, this defaults to your document root.\n\nThe component root defines how component paths are translated into real file paths. If your\ncomponent root is /usr/local/httpd/docs, a component path of /products/index.html translates to\nthe file /usr/local/httpd/docs/products/index.html.\n\nOne cannot call a component outside the component root. If Apache passes a file through Mason\nthat is outside the component root (say, as the result of an Alias) you will get a 404 and a\nwarning in the logs.\n\nYou may also specify multiple component roots in the spirit of Perl's @INC. Each root is\nassigned a key that identifies the root mnemonically. For example, in httpd.conf:\n\nPerlAddVar  MasonCompRoot  \"private => /usr/home/joe/comps\"\nPerlAddVar  MasonCompRoot  \"main => /usr/local/www/htdocs\"\n\nThis specifies two component roots, a main component tree and a private tree which overrides\ncertain components. The order is respected ala @INC, so *private* is searched first and *main*\nsecond.\n\nThe component root keys must be unique in a case-insensitive comparison. The keys are used in\nseveral ways. They help to distinguish component caches and object files between different\ncomponent roots, and they appear in the \"title()\" of a component.\n"
                },
                {
                    "name": "Data Directory",
                    "content": "The data directory (datadir) is a writable directory that Mason uses for various features and\noptimizations. By default, it is a directory called \"mason\" under your Apache server root.\nBecause Mason will not use a *default* data directory under a top-level directory, you will need\nto change this on certain systems that assign a high-level server root such as /usr or /etc.\n\nMason will create the directory on startup, if necessary, and set its permissions according to\nthe web server User/Group.\n"
                },
                {
                    "name": "External Modules",
                    "content": "Components will often need access to external Perl modules. There are several ways to load them.\n\n*   The httpd PerlModule directive:\n\nPerlModule CGI\nPerlModule LWP\n\n*   In the \"<%once>\" section of the component(s) that use the module.\n\n<%once>\nuse CGI ':standard';\nuse LWP;\n</%once>\n\nEach method has its own trade-offs:\n\nThe first method ensures that the module will be loaded by the Apache parent process at startup\ntime, saving time and memory. The second method, in contrast, will cause the modules to be\nloaded by each server child. On the other hand this could save memory if the component and\nmodule are rarely used. See the modperl guide's tuning section and Vivek Khera's modperl\ntuning guide for more details on this issue.\n\nThe second method uses the modules from inside the package used by components\n(\"HTML::Mason::Commands\"), meaning that exported method names and other symbols will be usable\nfrom components. The first method, in contrast, will import symbols into the \"main\" package. The\nsignificance of this depends on whether the modules export symbols and whether you want to use\nthem from components.\n\nIf you want to preload the modules in your httpd.conf file, and still have them export symbols\ninto the \"HTML::Mason::Commands\" namespace, you can do this:\n\n<Perl>\n{ package HTML::Mason::Commands;\nuse CGI;\nuse LWP;\n}\n</Perl>\n\nA Perl section will also work for including local library paths:\n\n<Perl>\nuse lib '/path/to/local/lib';\n</Perl>\n"
                },
                {
                    "name": "Allowing Directory Requests",
                    "content": "By default Mason will decline requests for directories, leaving Apache to serve up a directory\nindex or a FORBIDDEN as appropriate. Unfortunately this rule applies even if there is a dhandler\nin the directory: /foo/bar/dhandler does not get a chance to handle a request for /foo/bar/.\n\nIf you would like Mason to handle directory requests, set declinedirs to 0. The dhandler that\ncatches a directory request is responsible for setting a reasonable content type via\n\"$r->contenttype()\".\n"
                },
                {
                    "name": "Configuring Virtual Sites",
                    "content": "These examples extend the single site configurations given so far.\n\nMultiple sites, one component root\nIf you want to share some components between your sites, arrange your httpd.conf so that all\nDocumentRoots live under a single component space:\n\n# Web site #1\n<VirtualHost www.site1.com>\nDocumentRoot  /usr/local/www/htdocs/site1\n<LocationMatch ...>\nSetHandler   perl-script\nPerlHandler  HTML::Mason::ApacheHandler\n</LocationMatch>\n</VirtualHost>\n\n# Web site #2\n<VirtualHost www.site2.com>\nDocumentRoot  /usr/local/www/htdocs/site2\n<LocationMatch ...>\nSetHandler   perl-script\nPerlHandler  HTML::Mason::ApacheHandler\n</LocationMatch>\n</VirtualHost>\n\n# Mason configuration\nPerlSetVar  MasonCompRoot  /usr/local/www/htdocs\nPerlSetVar  MasonDataDir   /usr/local/mason\nPerlModule  HTML::Mason::ApacheHandler\n\nThe directory structure for this scenario might look like:\n\n/usr/local/www/htdocs/  # component root\n+- shared/          # shared components\n+- site1/           # DocumentRoot for first site\n+- site2/           # DocumentRoot for second site\n\nIncoming URLs for each site can only request components in their respective DocumentRoots, while\ncomponents internally can call other components anywhere in the component space. The shared/\ndirectory is a private directory for use by components, inaccessible from the Web.\n\nMultiple sites, multiple component roots\nIf your sites need to have completely distinct component hierarchies, e.g. if you are providing\nMason ISP services for multiple users, then the component root must change depending on the site\nrequested.\n\n<VirtualHost www.site1.com>\nDocumentRoot  /usr/local/www/htdocs/site1\n\n# Mason configuration\nPerlSetVar  MasonCompRoot    /usr/local/www/htdocs/site1\nPerlSetVar  MasonDataDir     /usr/local/mason/site1\n\n<LocationMatch ...>\nSetHandler   perl-script\nPerlHandler  HTML::Mason::ApacheHandler\n</LocationMatch>\n</VirtualHost>\n\n# Web site #2\n<VirtualHost www.site2.com>\nDocumentRoot  /usr/local/www/htdocs/site2\n\n# Mason configuration\nPerlSetVar  MasonCompRoot    /usr/local/www/htdocs/site2\nPerlSetVar  MasonDataDir     /usr/local/mason/site2\n\n<LocationMatch ...>\nSetHandler   perl-script\nPerlHandler  HTML::Mason::ApacheHandler\n</LocationMatch>\n</VirtualHost>\n"
                }
            ]
        },
        "ADVANCED CONFIGURATION": {
            "content": "As mentioned previously, it is possible to write a custom modperl content handler that wraps\naround Mason and provides basically unlimited flexibility when handling requests. In this\nsection, we show some basic wrappers and re-implement some of the functionality previously\ndiscussed, such as declining image requests and protecting private components.\n\nIn addition, we discuss some of the possibilities that become available when you create a custom\nwrapper around Mason's request handling mechanism. This wrapper generally consists of two parts.\nThe initialization portion, run at server startup, will load any needed modules and create\nobjects. The other portion is the \"handler()\" subroutine, which handles web page requests.\n",
            "subsections": [
                {
                    "name": "Writing a Wrapper",
                    "content": "To create a wrapper, you simply need to define a \"handler()\" subroutine in the package of your\nchoice, and tell modperl to use it as a content handler. The file that defines the \"handler()\"\nsubroutine can be a module, or you can simply load a simple file that contains this subroutine\ndefinition. The latter solution was, for a long time, the *only* way to configure Mason, and the\nfile used was traditionally called handler.pl.\n\nNowadays, we recommend that you create a custom module in the appropriate namespace and define\nyour \"handler()\" subroutine there. The advantage to this approach is that it uses well-known\ntechniques for creating and installing modules, but it does require a bit more work than simply\ndropping a script file into the Apache configuration directory. But because the process is\nbetter defined, it may \"feel\" more solid to some folks than the script approach.\n\nThe eg/ directory of the Mason distribution contains a couple sample modules that define\n\"handler()\" subroutines. Let's assume that your module, like the example, defines a \"handler()\"\nin the package \"MyApp::Mason\". In this case, your Apache configuration would look like this:\n\nPerlModule  MyApp::Mason\n\n<LocationMatch ...>\nSetHandler   perl-script\nPerlHandler  MyApp::Mason\n</LocationMatch>\n\nYou may still see references to a handler.pl file in the Mason users list archives, as well as\nthe FAQ. These references will generally be applicable to any custom code wrapping Mason.\n\nWrappers and PerlSetVar-style configuration\nSometimes people attempt to write a wrapper *and* configure Mason with \"PerlSetVar\" directives\nin their Apache configuration file. This does not work. When you give modperl this\nconfiguration:\n\nPerlHandler HTML::Mason::ApacheHandler\n\nit will dispatch directly to the \"HTML::Mason::ApacheHandler->handler()\" method, without ever\nexecuting your wrapper code. However, you can mix the two methods. See Mixing httpd.conf\nConfiguration with a Wrapper\n\nWrapping with a <Perl> block\nYou can also put your wrapper code in a \"<Perl>\" block as part of your httpd.conf file. The\nresult is no different than loading a file via the \"PerlRequire\" directive.\n"
                },
                {
                    "name": "The Wrapper Code",
                    "content": "Regardless of how you load your wrapper code, it will always work the same way. The \"handler()\"\nsubroutine should expect to receive the Apache request object representing the current request.\nThis request object is used by the ApacheHandler module to determine what component is being\ncalled.\n\nLet's look at the guts of some wrapper code. Here's a first version:\n\npackage MyApp::Mason;\n\nuse strict;\nuse HTML::Mason::ApacheHandler;\n\nmy $ah =\nHTML::Mason::ApacheHandler->new\n( comproot => '/path/to/comp/root',\ndatadir  => '/path/to/data/dir' );\n\nsub handler {\nmy ($r) = @;\n\nreturn $ah->handlerequest($r);\n}\n\nThis wrapper is fully functional, but it doesn't actually do anything you couldn't do more\neasily by configuring Mason via the httpd.conf file. However, it does serve as a good skeleton\nto which additional functionality can easily be added.\n"
                },
                {
                    "name": "External Modules Revisited",
                    "content": "Since you are loading an arbitrary piece of code to define your wrapper, you can easily load\nother modules needed for your application at the same time. For example, you might simple add\nthese lines to the wrapper code above:\n\n{\npackage HTML::Mason::Commands;\n\nuse MIME::Base64;\n}\n\nExplicitly setting the package to \"HTML::Mason::Commands\" makes sure that any symbols that the\nloaded modules export (constants, subroutines, etc.) get exported into the namespace under which\ncomponents run. Of course, if you've changed the component namespace, make sure to change the\npackage name here as well.\n\nAlternatively, you might consider creating a separate piece of code to load the modules you\nneed. For example, you might create a module called \"MyApp::MasonInit\":\n\n{\npackage HTML::Mason::Commands;\n\nuse Apache::Constants qw(:common);\nuse Apache::URI;\nuse File::Temp;\n}\n\n1;\n\nThis can be loaded via a \"PerlModule\" directive in the httpd.conf file, or in the wrapper code\nitself via \"use\".\n\nExample: Controlling access with component attributes\nAn example of something you can only do with wrapper code is deciding at run-time whether a\ncomponent can be accessed at the top-level based on a complex property of the component. For\nexample, here's a piece of code that uses the current user and a component's \"accesslevel\"\nattribute to control access:\n\nsub handler {\nmy ($r) = @;\n\nmy $req = $ah->preparerequest($r);\n\nmy $comp = $req->requestcomp;\n\n# this is done via magic hand-waving ...\nmy $user = getuserfromcookie();\n\n# remember, attributes are inherited so this could come from a\n# component higher up the inheritance chain\nmy $requiredaccess = $comp->attr('accesslevel');\n\nreturn NOTFOUND\nif $user->accesslevel < $requiredaccess;\n\nreturn $req->exec;\n}\n"
                },
                {
                    "name": "Wrappers with Virtual Hosts",
                    "content": "If you had several virtual hosts, each of which had a separate component root, you'd need to\ncreate a separate ApacheHandler object for each host, one for each host. Here's some sample code\nfor that:\n\nmy %ah;\nforeach my $site ( qw( site1 site2 site3 ) ) {\n$ah{$site} =\nHTML::Mason::ApacheHandler->new\n( comproot => \"/usr/local/www/$site\",\ndatadir => \"/usr/local/mason/$site\" );\n}\n\nsub handler {\nmy ($r) = @;\n\nmy $site = $r->dirconfig('SiteName');\n\nreturn DECLINED unless exists $ah{$site};\n\nreturn $ah{$site}->handlerequest($r);\n}\n\nThis code assumes that you set the \"SiteName\" variable via a \"PerlSetVar\" directive in each\n\"VirtualHost\" block, like this:\n\n<VirtualHost site1.example.com>\nPerlSetVar  SiteName  site1\n\n<LocationMatch ...>\nSetHandler   perl-script\nPerlHandler  MyApp::Mason\n</LocationMatch>\n</VirtualHost>\n\nCreating apachehandler objects on the fly\nYou might also consider creating ApacheHandler objects on the fly, like this:\n\nmy %ah;\nsub handler {\nmy ($r) = @;\nmy $site = $r->dirconfig('SiteName');\n\nreturn DECLINED unless $site;\n\nunless exists($ah{$site}) {\n$ah{$site} = HTML::Mason::ApacheHandler->new( ... );\n}\n\n$ah{$site}->handlerequest($r);\n}\n\nThis is more flexible but you lose the memory savings of creating all your objects during server\nstartup.\n\nOther uses for a wrapper\nIf you have some code which must *always* run after a request, then the only way to guarantee\nthat this happens is to wrap the \"$ah->handlerequest()\" call in an \"eval {}\" block, and then\nrun the needed code after the request returns. You can then handle errors however you like.\n"
                },
                {
                    "name": "Mixing httpd.conf Configuration with a Wrapper",
                    "content": "You can take advantage of Mason's httpd.conf configuration system while at the same time\nproviding your own wrapper code. The key to doing this is *not* creating your own ApacheHandler\nobject. Instead, you call the \"HTML::Mason::ApacheHandler->handler()\" class method from your\n\"handler()\" subroutine. Here's a complete wrapper that does this:\n\npackage MyApp::Mason;\n\nuse strict;\nuse HTML::Mason::ApacheHandler;\n\nsub handler {\nmy ($r) = @;\n\nreturn HTML::Mason::ApacheHandler->handler($r);\n}\n\nThe \"HTML::Mason::ApacheHandler->handler\" method will create an ApacheHandler object based on\nthe configuration directives it finds in your httpd.conf file. Obviously, this wrapper is again\na skeleton, but you could mix and match this wrapper code with any of the code shown above.\n\nAlternately you could subclass the \"HTML::Mason::ApacheHandler\" class, and override the\n\"handler()\" method it provides. See the Subclassing documentation for more details. Of course,\nyou could even create a subclass *and* write a wrapper that called it.\n"
                }
            ]
        },
        "DEVELOPMENT": {
            "content": "This section describes how to set up common developer features.\n",
            "subsections": [
                {
                    "name": "Global Variables",
                    "content": "Global variables can make programs harder to read, maintain, and debug, and this is no less true\nfor Mason components. Due to the persistent modperl environment, globals require extra\ninitialization and cleanup care.\n\nThat said, there are times when it is very useful to make a value available to all Mason\ncomponents: a DBI database handle, a hash of user session information, the server root for\nforming absolute URLs.\n\nBecause Mason by default parses components in \"strict\" mode, you'll need to declare a global if\nyou don't want to access it with an explicit package name. The easiest way to declare a global\nis with the allowglobals parameter.\n\nSince all components run in the same package, you'll be able to set the global in one component\nand access it in all the others.\n\nAutohandlers are common places to assign values to globals. Use the \"<%once>\" section if the\nglobal only needs to be initialized at load time, or the \"<%init>\" section if it needs to be\ninitialized every request.\n"
                },
                {
                    "name": "Sessions",
                    "content": "Mason does not have a built-in session mechanism, but you can use the\n\"MasonX::Request::WithApacheSession\" module, available from CPAN, to add a session to every\nrequest. It can also automatically set and read cookies containing the session id.\n"
                },
                {
                    "name": "Data Caching",
                    "content": "Data caching is implemented with DeWitt Clinton's \"Cache::Cache\" module. For full understanding\nof this section you should read the documentation for \"Cache::Cache\" as well as for relevant\nsubclasses (e.g. \"Cache::FileCache\").\n\nCache files\nBy default, \"Cache::FileCache\" is the subclass used for data caching, although this may be\noverridden by the developer. \"Cache::FileCache\" creates a separate subdirectory for every\ncomponent that uses caching, and one file some number of levels underneath that subdirectory\nfor each cached item. The root of the cache tree is datadir/\"cache\". The name of the cache\nsubdirectory for a component is determined by the function\n\"HTML::Mason::Utils::datacachenamespace\".\n\nDefault constructor options\nOrdinarily, when \"$m->cache\" is called, Mason passes to the cache constructor the\n\"namespace\", and \"cacheroot\" options, along with any other options given in the \"$m->cache\"\nmethod.\n\nYou may specify other default constructor options with the datacachedefaults parameter.\nFor example,\n\nPerlSetVar  MasonDataCacheDefaults  \"cacheclass => SizeAwareFileCache\"\nPerlAddVar  MasonDataCacheDefaults  \"cachedepth => 2\"\nPerlAddVar  MasonDataCacheDefaults  \"defaultexpiresin => 1 hour\"\n\nAny options passed to individual \"$m->cache\" calls override these defaults.\n\nDisabling data caching\nIf for some reason you want to disable data caching entirely, set the default \"cacheclass\"\nto \"NullCache\". This subclass faithfully implements the cache API but never stores data.\n"
                }
            ]
        },
        "PERFORMANCE": {
            "content": "This section explains Mason's various performance enhancements and how to administer them. One\nof the best ways to maximize performance on your production server is run in staticsource mode;\nsee the third subsection below.\n",
            "subsections": [
                {
                    "name": "Code Cache",
                    "content": "When Mason loads a component, it places it in a memory cache. By default, the cache has no\nlimit, but you can specify a maximum number of components to cache with the codecachemaxsize\nparameter. In this case, Mason will free up space as needed by discarding components. The\ndiscard algorithm is least frequently used (LFU), with a periodic decay to gradually eliminate\nold frequency information. In a nutshell, the components called most often in recent history\nshould remain in the cache.\n\nPrevious versions of Mason attempted to estimate the size of each component, but this proved so\ninaccurate as to be virtually useless for cache policy. The max size is now specified purely in\nnumber of components.\n\nMason can use certain optimizations with an unlimited cache, especially in conjunction with\nstaticsource, so don't limit the cache unless experience shows that your servers are growing\ntoo large. Many dynamic sites can be served comfortably with all components in memory.\n\nYou can prepopulate the cache with components that you know will be accessed often; see\nPreloading Components. Note that preloaded components possess no special status in the cache and\ncan be discarded like any others.\n\nNaturally, a cache entry is invalidated if the corresponding component source file changes.\n\nTo turn off code caching completely, set codecachemaxsize to 0.\n"
                },
                {
                    "name": "Object Files",
                    "content": "The in-memory code cache is only useful on a per-process basis. Each process must build and\nmaintain its own cache. Shared memory caches are conceivable in the future, but even those will\nnot survive between web server restarts.\n\nAs a secondary, longer-term cache mechanism, Mason stores a compiled form of each component in\nan object file under datadir/obj. Any server process can eval the object file and save time on\nparsing the component source file. The object file is recreated whenever the source file\nchanges.\n\nThe object file pathname is formed from three parts:\n\n*   the compiler \"objectid\" - this prevents different versions of Mason or compilers from using\nthe same object file, such as after an upgrade\n\n*   the component path\n\n*   objectfileextension, by default \".obj\"\n\nBesides improving performance, object files can be useful for debugging. If you feel the need to\nsee what your source has been translated into, you can peek inside an object file to see exactly\nhow Mason converted a given component to a Perl object. This was crucial for pre-1.10 Mason, in\nwhich error line numbers were based on the object file rather than the source file.\n\nIf for some reason you don't want Mason to create object files, set useobjectfiles to 0.\n"
                },
                {
                    "name": "Static Source Mode",
                    "content": "In staticsource mode, Mason assumes that the component hierarchy is unchanging and thus does\nnot check source timestamps when using an in-memory cached component or object file. This\nsignificantly reduces filesystem stats and other overhead. We've seen speedups by a factor of\ntwo or three as a result of this mode, though of course YMMV.\n\nWhen in staticsource mode, you must remove object files and call $interp->flushcodecache in\norder for the server to recognize component changes. The easiest way to arrange this is to point\nstaticsourcetouchfile to a file that can be touched whenever components change.\n\nWe highly recommend running in this mode in production if you can manage it. Many of Mason's\nfuture optimizations will be designed for this mode. On development servers, of course, it makes\nsense to keep this off so that components are reloaded automatically.\n"
                },
                {
                    "name": "Disabling Autoflush",
                    "content": "To support the dynamic autoflush feature, Mason has to check for autoflush mode after printing\nevery piece of text. If you can commit to not using autoflush, setting enableautoflush to 0\nwill allow Mason to compile components more efficiently. Consider whether a few well-placed\n\"$m->flushbuffer\" calls would be just as good as autoflush.\n"
                },
                {
                    "name": "Write a handler subroutine",
                    "content": "Writing your own \"handler()\" subroutine which uses an ApacheHandler object (or objects) created\nduring server startup is slightly faster (around 5% or so) than configuring mason via your\nhttpd.conf file and letting Mason create its own ApacheHandler objects internally.\n"
                },
                {
                    "name": "Preloading Components",
                    "content": "You can tell Mason to preload a set of components in the parent process, rather than loading\nthem on demand, using the preloads parameter. Each child server will start with those components\nloaded in the memory cache. The trade-offs are:\n\ntime\na small one-time startup cost, but children save time by not having to load the components\n\nmemory\na fatter initial server, but the memory for preloaded components are shared by all children.\nThis is similar to the advantage of using modules only in the parent process.\n\nTry to preload components that are used frequently and do not change often. (If a preloaded\ncomponent changes, all the children will have to reload it from scratch.)\n"
                },
                {
                    "name": "Preallocating the Output Buffer",
                    "content": "You can set bufferpreallocatesize to set the size of the preallocated output buffer for each\nrequest. This can reduce the number of reallocations Perl performs as components output text.\n"
                }
            ]
        },
        "ERROR REPORTING AND EXCEPTIONS": {
            "content": "When an error occurs, Mason can respond by:\n\n*   showing a detailed error message in the browser in HTML.\n\n*   die'ing, which sends a 500 status to the browser and lets the error message go to the error\nlogs.\n\nThe first behavior is ideal for development, where you want immediate feedback on the error. The\nsecond behavior is usually desired for production so that users are not exposed to messy error\nmessages. You choose the behavior by setting errormode to \"output\" or \"fatal\" respectively.\n\nError formatting is controlled by the errorformat parameter. When showing errors in the\nbrowser, Mason defaults to the \"html\" format. When the errormode is set to \"fatal\", the default\nformat is \"line\", which puts the entire error message on one line in a format suitable for web\nserver error logs. Mason also offers other formats, which are covered in the Request class\ndocumentation.\n\nFinally, you can use Apache's \"ErrorDocument\" directive to specify a custom error handler for\n500 errors. In this case, you'd set the errormode to \"fatal\". The URL specified by the\n\"ErrorDocument\" directive could point to a Mason component.\n",
            "subsections": [
                {
                    "name": "Exceptions Under the Hood",
                    "content": "The way that Mason really reports errors is through the use of exception objects, which are\nimplemented with the \"Exception::Class\" module from CPAN, and some custom code in the\nHTML::Mason::Exceptions module.\n\nIf, during the execution of a component, execution stops because some code calls \"die()\", then\nMason will catch this exception. If the exception being thrown is just a string, then it will be\nconverted to an \"HTML::Mason::Exception\" object. If the exception being thrown is an object with\na \"rethrow()\" method, then this method will be called. Otherwise, Mason simply leaves the\nexception untouched and calls \"die()\" again.\n\nCalling a Component to Handle Errors\nReturning to the topic of wrapper code that we covered earlier, what if you wanted to handle all\nrequest errors by calling an error handling component? There is no way to do this without\nwrapper code. Here's an example \"handler()\" subroutine that does this:\n\nsub handler {\nmy ($r) = @;\n\nmy $return = eval { $ah->handlerequest($r) };\n\nif ( my $err = $@ )\n{\n$r->pnotes( error => $err );\n$r->filename( $r->documentroot . '/error/500.html' );\n\nreturn $ah->handlerequest($r);\n}\n\nreturn $return;\n}\n\nFirst, we wrap our call to \"$ah->handlerequest()\" in an \"eval{}\" block. If an error occurs, we\nstore it in the request object using the \"$r->pnotes()\" method. Then we change the filename\nproperty of the Apache request object to point to our error-handling component and call the\n\"$ah->handlerequest()\" method again, passing it the altered request object. We could have put\nthe exception in \"$r->args\", but we want to leave this untouched so that the error-handling\ncomponent can see the original arguments.\n\nHere's what that component error-handling component might look like:\n\n<html>\n<head>\n<title>Error</title>\n</head>\n\n<body>\n\n<p>\nLooks like our application broke.  Whatever you did, don't do it again!\n</p>\n\n<p>\nIf you have further questions, please feel free to contact us at <a\nhref=\"mailto:support@example.com\">support@example.com</a>.\n</p>\n\n<p><a href=\"/\">Click here</a> to continue.</p>\n\n</body>\n</html>\n\n<%init>\nmy $error = $r->pnotes('error');\n\nmy $errortext = \"Page is \" . $r->parseduri->unparse . \"\\n\\n\";\n\n$errortext .= UNIVERSAL::can( $error, 'astext' ) ? $error->astext : $error;\n\n$r->logerror($errortext);\n\nmy $mail =\nMIME::Lite->new\n( From => 'error-handler@example.com',\nTo   => 'rt@example.com',\nSubject => 'Application error',\nData => $errortext,\n);\n\n$r->registercleanup( sub { $mail->send } );\n</%init>\n\n<%flags>\ninherit => undef\n</%flags>\n\nThis component does several things. First of all, it logs the complete error to the Apache error\nlogs, along with the complete URL, including query string, that was requested. The\n\"$r->parseduri()\" method that we use above is only available if the \"Apache::URI\" module has\nbeen loaded.\n\nThe component also sends an email containing the error, in this case to an RT installation, so\nthat the error is logged in a bug tracking system. Finally, it displays a less technical error\nmessage to the user.\n\nFor this to work properly, you must set errormode to \"fatal\", so that Mason doesn't just\ndisplay its own HTML error page.\n"
                }
            ]
        },
        "RUNNING OUTSIDE OF MODPERL": {
            "content": "Although Mason is most commonly used in conjunction with modperl, the APIs are flexible enough\nto use in any environment. Below we describe the two most common alternative environments, CGI\nand standalone scripts.\n",
            "subsections": [
                {
                    "name": "Using Mason from a CGI Script",
                    "content": "The easiest way to use Mason via a CGI script is with the CGIHandler module module.\n\nHere is a skeleton CGI script that calls a component and sends the output to the browser.\n\n#!/usr/bin/perl\nuse HTML::Mason::CGIHandler;\n\nmy $h = HTML::Mason::CGIHandler->new\n(\ndatadir  => '/home/jethro/code/masondata',\n);\n\n$h->handlerequest;\n\nThe relevant portions of the httpd.conf file look like:\n\nDocumentRoot /path/to/comp/root\nScriptAlias /cgi-bin/ /path/to/cgi-bin/\n\n<LocationMatch \"\\.html$\">\nAction html-mason /cgi-bin/masonhandler.cgi\nAddHandler html-mason .html\n</LocationMatch>\n<LocationMatch \"^/cgi-bin/\">\nRemoveHandler .html\n</LocationMatch>\n<FilesMatch \"(autohandler|dhandler)$\">\nOrder allow,deny\nDeny from all\n</FilesMatch>\n\nThis simply causes Apache to call the masonhandler.cgi script every time a URL ending in\n\".html\" under the component root is requested.\n\nTo exclude certain directories from being under Mason control, you can use something like the\nfollowing:\n\n<LocationMatch \"^/(dir1|dir2|dir3)/\">\nRemoveHandler .html\n</LocationMatch>\n\nThis script uses the CGIHandler class to do most of the heavy lifting. See that class's\ndocumentation for more details.\n"
                },
                {
                    "name": "Using Mason from a Standalone Script",
                    "content": "Mason can be used as a pure text templating solution -- like Text::Template and its brethren,\nbut with more power (and of course more complexity).\n\nHere is a bare-bones script that calls a component file and sends the result to standard output:\n\n#!/usr/bin/perl\nuse HTML::Mason;\nuse strict;\n\nmy $interp = HTML::Mason::Interp->new ();\n$interp->exec(<relative path to file>, <args>...);\n\nBecause no component root was specified, the root is set to your current working directory. If\nyou have a well defined and contained component tree, you'll probably want to specify a\ncomponent root.\n\nBecause no data directory was specified, object files will not be created and data caching will\nnot work in the default manner. If performance is an issue, you will want to specify a data\ndirectory.\n\nHere's a slightly fuller script that specifies a component root and data directory, and captures\nthe result in a variable rather than sending to standard output:\n\n#!/usr/bin/perl\nuse HTML::Mason;\nuse strict;\n\nmy $outbuf;\nmy $interp = HTML::Mason::Interp->new\n(comproot  => '/path/to/comproot',\ndatadir   => '/path/to/datadir',\noutmethod => \\$outbuf\n);\n$interp->exec(<component-path>, <args>...);\n\n# Do something with $outbuf\n"
                }
            ]
        }
    },
    "summary": "HTML::Mason::Admin - Mason Administrator's Manual",
    "flags": [],
    "examples": [],
    "see_also": []
}