Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MasonX::WebApp(3)     User Contributed Perl Documentation    MasonX::WebApp(3)

NAME
       MasonX::WebApp -	Works with Mason to do processing before Mason is
       invoked

SYNOPSIS
	 # Create a subclass of	MasonX::WebApp
	 package My::WebApp;

	 use base 'MasonX::WebApp';

	 sub _init
	 {
	     # do something interesting, like making sure all incoming
	     # arguments are UTF-8
	 }

	 # Create a handler() for it

	 package My::MasonHandler;

	 my $ah	= MasonX::WebApp::ApacheHandler->new( ... );

	 sub handler
	 {
	     # see docs	for details
	 }

	 # In your Apache config file

	 <Location />
	   SetHandler	perl-script
	   PerlHandler	My::MasonHandler
	 </Location>

DESCRIPTION
       "MasonX::WebApp"	works with Mason to let	you do processing before Mason
       is ever invoked.	 There are a number of things that one might want to
       do:

       o   Argument munging

	   You might want to make sure all incoming arguments are UTF-8
	   encoded.  Or	you might want to create some objects which Mason will
	   see as incoming arguments.  For example, a "user_id"	parameter
	   could be turned into	a user object.

       o   Handle requests without Mason

	   If you're not generating output for the browser other than a
	   redirect, then there's no reason to use Mason.  You can use a
	   "MasonX::WebApp" subclass to	handle all form	submissions, for
	   example.

	   This	has the	added benefit of making	it easier to preload this code
	   once	during server startup.

       o   Authorization checks

	   Why do authorization	checks in Mason	if a failed check just leads
	   to a	redirect or NOT	FOUND return code?

USAGE
       To use "MasonX::WebApp",	you should create a "MasonX::WebApp" subclass.
       By itself, "MasonX::WebApp" won't do a whole lot	for you, but it
       provides	a nice framework for building on.

   What	MasonX::WebApp Provides
       "MasonX::WebApp", out of	the box, provides the following:

       o   Session creation

	   You can declare your	session	parameters, and	"MasonX::WebApp" will
	   create an "Apache::Session::Wrapper"	object for you,	available via
	   the "session()" method.  Alternately, you can implement your	own
	   session creation method in your subclass.

       o   Argument munging

	   The arguments which will eventually be passed to Mason are
	   available via the "args()" method.  This method returns a hashref,
	   and any changes made	to this	reference will affect the arguments
	   eventually passed to	Mason.

       o   "Actions"

	   "MasonX::WebApp" will call appropriate methods based	on the URI.
	   These methods are determined	by removing a prefix from the URI
	   (settable via a class method), and then using the remainder as a
	   method name to be called on the webapp object.

       o   Generate output without using Mason

	   If you want to generate output that doesn't really need, like
	   sending a PDF file for download, you	can do that with your webapp
	   object before Mason is invoked.

       o   Messages, errors, and "saved	arguments"

	   If you are using sessions, the webapp object	provides methods to
	   store regular messages, error messages, and save arguments (to re-
	   populate a form, for	example) in the	session.  It also provides
	   methods to retrieve these.

       o   Convenient uri creation

	   The "uri()" method provides a nice flexible API for creating	URIs.

       You can set some	parameters for your subclass declaratively, by calling
       class methods.  These methods store data	using
       "Class::Data::Inheritable", so you can inherit from your	subclasses and
       inherit these parameters.

   Declarative Parameters
       The following class methods are offered for declaring parameters:

       o   ActionURIPrefix

	   This	is the prefix used to determine	which, if any, "action"	method
	   should be called on the webapp object.  By default, this is
	   /submit/.  So if a request comes in for /submit/login, then the
	   "login()" method will be called.

	   If you change this, your prefix must	also start and with a slash
	   (/).

	   Setting this	will override a	previous setting of
	   "ActionURIPrefixRegex", so do not set both of these parameters in
	   your	subclass.

       o   ActionURIPrefixRegex

	   If you want to do something more complex than specifying one
	   prefix, you can use this method to specify a	regex which determines
	   if a	URI is calling an action.  For example,	you might want to
	   allow both /submit/ and /download/ as prefixes:

	     $self->ActionURIPrefixRegex( qr{^/(?:submit|download)/} );

       o   ApacheHandlerParams

	   This	should be a hash reference of options that will	be passed to
	   the "MasonX::WebApp::ApacheHandler" class's "new()" method when
	   creating a new ApacheHandler	object.	 You don't need	to set this if
	   you are creating the	ApacheHandler from scratch in your subclass,
	   and/or if you are providing your own	mod_perl "handler()"
	   subroutine/method.

	   The default "handler()" will	create a new
	   "MasonX::WebApp::ApacheHandler" object on every request, using
	   these parameters.

       o   MasonGlobalName

	   The variable	name to	use for	the webapp object in Mason components.
	   The default "handler()" sets	this global.

	   The default value for this is $WebApp.

       o   RequireAbortAfterAction

	   If this is true, then an exception will be thrown if	an action is
	   handled but no abort	is generated inside the	action method.	A
	   redirect is a form of abort.

	   This	defaults to true.

       o   SessionWrapperParams

	   A hash reference of parameters to be	passed to the
	   "Apache::Session::Wrapper" class's "new()" method.

	   You don't need to set this if you are creating your own session
	   wrapper object.

	   Setting this	also causes "UseSession" to be set to a	true value.

       o   UseSession

	   Set this to true if you are creating	your own session wrapper
	   object, so that "MasonX::WebApp" knows it can call "session()"
	   internally.

   Exceptions
       Some methods throw exceptions.  Exceptions classes are created using
       "Exception::Class".

   Public Methods
       The folowing methods are	public,	and can	be called from subclasses or
       from elsewhere, like in Mason components.

       o   new()

	   This	is the constructor method.  It expects to receive at least two
	   arguments:

	   o	   apache_req

		   An Apache request object, which must	be an "Apache" object
		   or a	subclass's object.

	   o	   args

		   A hash reference of arguments.  If you are using the
		   "MasonX::WebApp::ApacheHandler" class, you can use the
		   return value	of its "request_args()"	method.

	   The new method will do the following:

	   Call	"_set_session()" if "UseSession()" is true.

	   Call	"_init()".  If additional arguments are	given then they	will
	   be passed along to your "_init()" method, if	you have one.  The
	   call	to "_init()" is	wrapped	in an eval block.  If an exception is
	   thrown, and that exception is not a
	   "MasonX::WebApp::Exception::Redirect" exception, then it will be
	   rethrown.  Redirect exceptions are not rethrown.

	   Call	"_handle_action()".

	   Return the newly created webapp object.

       o   apache_req()

	   Returns the Apache request given to the "new()" method.

       o   args()

	   Returns a hash reference containing the arguments passed to the
	   "new()" method.  Since this is the same reference as	is stored in
	   the "MasonX::WebApp::ApacheHandler" object, any changes to this
	   reference will be visible to	Mason components.

       o   session_wrapper()

	   Returns the "Apache::Session::Wrapper" object for the webapp
	   object.

	   If "UseSession()" is	not true, calling this method throws an
	   exception.

       o   session()

	   A shortcut for calling "$webapp->session_wrapper->session".

	   If "UseSession()" is	not true, calling this method throws an
	   exception.

       o   redirect()

	   This	method can take	a number of named parameters.  If it is	given
	   a "uri" parameter, then it uses this	URI for	the redirection.
	   Otherwise, it takes any parameters it is given and calls the
	   "uri()" method with them.  When it calls "uri()", it	sets the
	   "xhtml" parameter to	false, so you do not need to do	this.

	   If called inside the	context	of a Mason request, it calls
	   "redirect()"	on the Mason request object.

	   Otherwise it	sets the value of "aborted()" to true, sends a
	   redirect using the apache request object, and then throws a
	   "MasonX::WebApp::Exception::Aborted"	exception.

       o   abort( $status )

	   Stops processing by throwing	a "MasonX::WebApp::Exception::Aborted"
	   exception.  You can pass a status code (from	"Apache::Constants")
	   as an optional argument.  If	nothing	is given then this will
	   default to "OK".  This status code will be available	via the
	   "status_code()" method.

	   You will need to use	this method if you generate your own output in
	   an action handling method and don't want to pass control to Mason
	   afterwards.

       o   aborted()

	   Returns a boolean value indicating whether or not "abort()" has
	   been	called on the webapp object.  This will	be true	if the
	   "redirect()"	method was called, since it uses "abort()".

       o   abort_status()

	   The value passed to the "abort()" method.  If no value was passed,
	   this	will the "OK" constant from "Apache::Constants".

       o   uri()

	   This	creates	a URI string based on the parameters it	receives.  It
	   accepts the following parameters:

	   o	   path

		   The path portion of the URI.	 This is the only required
		   parameter.

	   o	   query

		   A hash reference which will be turned into a	query string.
		   The keys of the hash	reference may point to scalars,	array
		   references, or hash references.  Hash reference values are
		   treated the same way	as array references.

	   o	   fragment

		   Optional

	   o	   host

		   Optional.  By default, URIs are relative, and this is not
		   used.

	   o	   port

		   Optional.  This is ignored unless "host" is also passed.

	   o	   scheme

		   Defaults to "http", but since URIs are relative by default,
		   this	is ignored unless "host" is also passed.

	   o	   username

	   o	   password

		   Optional.  These are	both ignored unless "host" is also
		   passed.  If "password" is passed without a "username", it
		   is ignored.

	   o	   xhtml

		   Defaults to true.  If this is true, then the	returned URI
		   will	have any ampersands (&)	in the query string HTML-
		   escaped (&amp;).

       o   messages()

	   Returns an array of non-error messages stored in the	session.  This
	   method is destructive, as calling it	removes	the messages from the
	   session.

	   If you are not using	sessions, calling this method throws an
	   exception.

       o   errors()

	   Returns an array of error messages stored in	the session.  This
	   method is destructive, as calling it	removes	the error messages
	   from	the session.

	   If you are not using	sessions, calling this method throws an
	   exception.

       o   saved_args()

	   Returns a hash reference of arguments saved in the session.	This
	   method is not destructive.  If you are saving arguments in the
	   session, you	should probably	make sure that "clean_session()" is
	   called at the end of	every request.	The default "handler()"	sub
	   does	this.

	   If you are not using	sessions, calling this method throws an
	   exception.

       o   clean_session()

	   Removes any messages, error messages, and saved args	stored in the
	   session.  This should be called a the end of	each request in	order
	   to prevent these value leaking over into the	next request.

	   If you are not using	sessions, calling this method throws an
	   exception.

   Protected Methods
       These methods are intended to be	called directly	or overridden by your
       subclass.

       o   _LoadActions()

	   If you want to define actions in other files, like
	   "My::WebApp::User", this method provides a handy way	to load	all of
	   them	at once.  It looks for modules under your subclass's package
	   name	and loads them.	 So if your subclass is	in the package
	   "My::WebApp", then it looks for modules matching "My::WebApp::*".

	   Note	that because "MasonX::WebApp" will call	action methods on
	   $self, all of these modules must set	the package to the same	thing.
	   In the example, above, all of the action modules would need to set
	   their package to "My::WebApp".

	   You can always override "_handle_action()" to implement your	own
	   action dispaching if	you dislike this restriction.

       o   _init()

	   Called from the "new()" method.  By default this does nothing, but
	   you can override it to do something interesting with	the newly
	   created object.

       o   _is_valid_action()

	   This	method takes an	action name and	returns	a boolean value
	   indicating whether or not the action	is valid.  By default, this
	   simply checks if "$self->can($action)", but you should consider
	   overriding this to restrict what methods can	be called via a	URI.

       o   _make_session_wrapper()

	   This	method is called during	object construction if "UseSession" is
	   true.  By default, it creates a new "Apache::Session::Wrapper"
	   object with the parameters from "SessionWrapperParams".  You	can
	   override this method	to provide your	own session wrapper creation.

       o   _handle_action()

	   This	method is called during	object construction.  If a redirect
	   was done earlier in the object creation process, then it does
	   nothing.  Otherwise,	it looks at the	requested URI to see if	it
	   matches the "ActionURIPrefix".  If it does, it turns	the URI	into a
	   method name by stripping off	the prefix, and	it calls that method
	   on the webapp object.

	   You can override this to provide your own dispatching system	for
	   requests.

	   Note	that this method should	not call out to	Mason.	It should only
	   be used for actions that don't need Mason.

       o   _save_arg()

	   Given a key and value, this method saves them in the	session	so
	   that	they will be available via the "saved_args()" method.

	   If "UseSession()" is	not true, calling this method throws an
	   exception.

       o   _add_message()

	   Given a string, this	method stores that string in the session so
	   that	it is available	via the	"messages()" method.

	   If "UseSession()" is	not true, calling this method throws an
	   exception.

       o   _add_error_message()

	   Given a string, this	method stores that string in the session so
	   that	it is available	via the	"errors()" method.

	   If "UseSession()" is	not true, calling this method throws an
	   exception.

       o   _handle_error()

	   This	method can be used to handle exceptions	that occur during
	   actions.

	   It provides a quick way to store error messages and arguments in
	   the session,	and then issue a redirect.

	   It takes several parameters:

	   o	   error

		   This	should be either a scalar, an array reference or an
		   object.  If it is a scalar, this is assumed to be an	error
		   message.  If	it an array reference, it is assumed to	be an
		   array reference of scalars, each of which contains a	single
		   message.

		   If an object	is given, then it first	looks for a
		   "messages()"	method in that object.	This method should
		   return an array of scalars, each of which represents	an
		   error message.

		   Otherwise it	looks for a method called "message()", which
		   should return a single scalar.

		   It adds each	error message to the session via the
		   "_add_error_message()" method.

	   o	   save_args

		   This	is a hash reference of arguments that should be	saved
		   in the session.  Each key/value pair	will be	saved by
		   calling the the "_save_arg()" method.

	   All other arguments are passed along	to the "redirect()" method.

	   If "UseSession()" is	not true, calling this method throws an
	   exception.

       o   _apache_handler_object()

	   This	method is called in the	default	"handler()" method in order to
	   create a new	"MasonX::WebApp::ApacheHandler"	object.	 It simply
	   calls that class's "new()" method with the parameters set via
	   "ApacheHandlerParams".

   Hash	Keys in	the WebApp and Session Objects
       In order	to avoid stepping on your toes,	all hash keys in the webapp
       object, and all keys that it creates in the session object, are of the
       form "__blahblah__".  In	other words, they always start and end with
       two underscores (__).  This should make it easy to avoid	name conflicts
       when subclassing	this module or when using the session it provides.

   The Default handler() Method
       The "MasonX::WebApp" class provides a default handler method.

       I would recommend that instead of using this method, you	create your
       own mod_perl handler that does something	similar, because the default
       is not very efficient, given that it creates a new
       "MasonX::WebApp::ApacheHandler" object for each request.	 It is
       provided	primarily as a reference implementation, and so	that others
       can experiment with this	webapp code quickly.

       When creating your own handler, it might	be useful to copy the one in
       this module as a	reference.

       In your own handler, there are several important	guidelines you should
       follow.

       o   First of all, your "handler()" should use the
	   "MasonX::WebApp::ApacheHandler" class for the ApacheHandler object,
	   not "HTML::Mason::ApacheHandler".  The MasonX subclass caches the
	   value of "request_args()".  This is done so that these arguments
	   can be passed to the	"MasonX::WebApp" constructor and still be made
	   available to	Mason.	It also	makes sure that	Mason's	arguments are
	   the same hash reference as is available from	the "args()" method.
	   This	is very	important if you want to do any	argument munging in
	   your	subclass.  Also, since mod_perl	will only read POSTed data
	   once, without this caching Mason would not see any arguments	at
	   all!

       o   Get the request arguments by	calling	"request_args()" on the
	   ApacheHandler object, passing an "Apache" object as the method's
	   argument.  Unless you set the ApacheHandler's "args_method"
	   parameter to	"CGI", you must	pass in	an "ApacheRequest" object.

	   You will need to pass the hash reference returned by	this method to
	   the constructor for your WebApp object.

       o   After creating a new	webapp object, make sure to check the value of
	   the "aborted()" method for that object.  If it is true, you should
	   return the status code given	by the "abort_status()"	method from
	   your	"handler()".  Remember,	this will default to "OK" if no	status
	   was given to	the "abort()" method.

       o   If you are using the	message, error message,	or saved arg features,
	   you should make sure	that "clean_session()" is called at the	end of
	   every request.  This	means that you need to wrap the	call to	the
	   ApacheHandler's "handle_request()" method in	an eval	block, as in
	   the default "handler()"

       o   If you use the "set_global()" method	to make	the webapp object
	   available to	your components, and your ApacheHandler	objects
	   persist across requests, then you need to call "set_global()" again
	   after the request is	handled, and this time set that	global to
	   undef.  This	ensures	that the webapp	object will be destroyed.

	   A safer alternative,	if you know what class your components will be
	   compiled in,	is to do this:

	    local $HTML::Mason::Commands::App =	$app;

	   The use of "local" ensures that $app	will go	out of scope at	the
	   end of "handler()" subroutine.

       You can,	of course, do anything you want	in your	own "handler()"
       method.	I often	create an "Apache::Request" object with	a "POST_MAX"
       parameter, in order to prevent a	DoS from a ridiculously	large POST.

       I also often handle errors without dying, and instead will log them and
       present a more friendly page to the user.  If you want to do this, keep
       in mind that constructing a webapp object can throw exceptions, so you
       may want	to trap	these in an "eval" block.

       If you do something cool	with this code,	write about it on the Mason HQ
       site, masonhq.com (which	is a big wiki),	or send	a post to the Mason
       users list.

       Example handler()

       Here is an example of an	alternate handler().  This one is written as a
       function, not a method.

	 package My::MasonHandler;

	 sub handler
	 {
	     my	$apr = Apache::Request->new(shift);

	     my	$args =	$ah->request_args($apr);

	     my	$app = $class->new( apache_req => $apr,	args =>	$args );

	     return $app->abort_status if $app->aborted;

	     local $My::ComponentPackage::WebApp = $app;

	     my	$return	= eval { $ah->handle_request($r) };

	     my	$err = $@;

	     $app->clean_session if $class->UseSession;

	     die $err if $err;

	     return $return;
	  }

       Then in your Apache configuration, you would use	this handler:

	 <Location />
	   SetHandler	perl-script
	   PerlHandler	My::MasonHandler
	 </Location>

SEE ALSO
       If you like the basic idea of this code (run things before a Mason
       component is invoked), but you don't want to create a subclass, I
       encourage you to	take a look at David Wheeler's
       "MasonX::Interp::WithCallbacks" module.	In fact, I encourage you to
       take a look at it anyway, since it may be more appropriate than this
       one, depending on your needs.

SUPPORT
       Bug reports and requests	for help should	be sent	to the mason-users
       list.  See http://www.masonhq.com/resources/mailing_lists.html for more
       details.

AUTHOR
       Dave Rolsky, <autarch@urth.org>

COPYRIGHT
       This program is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself.

       The full	text of	the license can	be found in the	LICENSE	file included
       with this module.

perl v5.32.1			  2021-09-18		     MasonX::WebApp(3)

NAME | SYNOPSIS | DESCRIPTION | USAGE | SEE ALSO | SUPPORT | AUTHOR | COPYRIGHT

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=MasonX::WebApp&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help