Apache::RPC::Server - A subclass of RPC::XML::Server tuned for mod_perl |
server(s)
Apache::RPC::Server - A subclass of RPC::XML::Server tuned for mod_perl
# In httpd.conf: PerlModule Apache::RPC::Server PerlSetVar RpcMethodDir /var/www/rpc:/usr/lib/perl5/RPC-shared PerlChildInitHandler Apache::RPC::Server->init_handler ... <Location /RPC> SetHandler perl-script PerlHandler Apache::RPC::Server </Location> </Location /RPC-limited> SetHandler perl-script PerlHandler Apache::RPC::Server PerlSetVar RPCOptPrefix RpcLimit PerlSetVar RpcLimitRpcServer Limited PerlSetVar RpcLimitRpcMethodDir /usr/lib/perl5/RPC-shared </Location>
# In the start-up Perl file: use Apache::RPC::Server;
The Apache::RPC::Server module is a subclassing of RPC::XML::Server that is tuned and designed for use within Apache with mod_perl.
Provided are phase-handlers for the general request-processing phase
(PerlHandler
) and the child-process initialization phase
(PerlChildInitHandler
). The module should be loaded either by inclusion in a
server start-up Perl script or by directives in the server configuration file
(generally httpd.con). One loaded, the configuration file may assign the
module to handle one or more given locations with the general set of
<Location>
directives and familiar options. Additional configuration
settings specific to this module are detailed below.
Generally, externally-available methods are provided as files in the XML dialect explained in RPC::XML::Server. A subclass derived from this class may of course use the methods provided by this class and its parent class for adding and manipulating the method table.
The methods that the server publishes are provided by a combination of the installation files and Apache configuration values. Details on remote method syntax and semantics is covered in RPC::XML::Server.
In addition to inheriting all the methods from RPC::XML::Server, the following methods are either added or overloaded by Apache::RPC::Server:
This routine takes care of examining the incoming request, choosing an appropriate server object to actually process the request, and returning the results of the remote method call to the client.
PerlChildInitHandler
. At present, its only function is to iterate over all
server object currently in the internal tables and invoke the child_started
method (detailed below) on each. Setting this handler assures that each child
has a correct impression of when it started as opposed to the start time of the
server itself.
Note that this is only applied to those servers known to the master Apache process. In most cases, this will only be the default server object as described above. That is because of the delayed-loading nature of all servers beyond the default, which are likely only in child-specific memory. There are some configuration options described in the next section that can affect and alter this.
new(HASH)
new
method, then
performs some additional steps. These include installing the default methods
(which includes an Apache-specific version of system.status
), adding the
installation directory of this module to the method search path, and adding any
directories or explicitly-requested methods to the server object.
The arguments to the constructor are regarded as a hash table (not a hash reference), and are mostly passed unchanged to the constructor for RPC::XML::Server. Three parameters are of concern to this class:
Apache->server
(see Apache) is used.
The server identification string and prefix concepts are explained in more detail in the next section. See RPC::XML::Server for a full list of what additional arguments may be passed to new for eventual proxy to the parent class constructor.
child_started([BOOLEAN])
started
method provided by
RPC::XML::Server. When called with no argument or an argument that evaluates
to a false value, it returns the UNIX-style time value of when this child
process was started. Due to the child-management model of Apache, this may very
well be different from the value returned by started
itself. If given an
argument that evaluates as true, the current system time is set as the new
child-start time.
If the server has not been configured to set this at child initialization, then
the main started
value is returned. The name is different so that a child
may specify both server-start and child-start times with clear distinction.
get_server(APACHEREQ|STRING)
If the requested server object does not yet exist, an attempt will be made to create it and add it to the internal table. The newly-created object is then returned.
In addition to the known directives such as PerlHandler
and
PerlChildInitHandler
, configuration of this system is controlled through a
variety of settings that are manipulated with the PerlSetVar
and
PerlAddVar
directives. These variables are:
<Location>
block
to ensure that no settings from a higher point in the hierarchy influence the
server being defined.
<default>
''. If more than one server is going to be created
within the same Apache environment, this setting should always be used outside
the default area so that the default server is not loaded down with extra
method definitions. If a sub-location changes the default server, those changes
will be felt by any location that uses that server.
Different locations may share the same server by specifying the name with this variable. This is useful for managing varied access schemes, traffic analysis, etc.
*.xpl
files. To specify more than one directory, separate them with ``:
'' just as
with any other directory-path expression. All directories are kept (in the
order specified) as the search path for future loading of methods.
server(s)
Methods are provided to an Apache::RPC::Server object in three ways:
RpcDefMethods
option, the methods shipped with this
package are loaded into the table. The Apache::RPC::Server objects get a
slightly different version of system.status
than the parent class does.
*.xpl
) in the directories
specified in the relevant RpcMethodDir
settings are read next. These
directories are also (after the next step) added to the search path the object
uses.
RpcMethod
settings are loaded
last. This allows for them to override methods that may have been loaded from
the system defaults or the specified directories.
If a request is made for an unknown method, the object will first attempt to
find it by searching the path of directories that were given in the
configuration as well as those that are part of the system (installation-level
directories). If it is still not found, then an error is reported back to the
requestor. By using this technique, it is possible to add methods to a running
server without restarting it. It is a potential security hole, however, and it
is for that reason that the previously-documented RpcAutoMethods
setting is
provided.
To truly unlock the power of having the RPC server attached to a mod_perl environment, the application and configuration of the server should be done within Perl-configuration blocks on the Apache server itself.
In doing this, two immediate benefits are gained:
The following example illustrates these concepts in a fairly simple environment:
# In httpd.conf: <Perl>
# First, create and configure some Apache::RPC::Server objects
# One regular one, with the standard settings: $main::defobj = Apache::RPC::Server->new(path => '/RPC', auto_methods => 1, auto_updates => 1); # One version without the default methods, and no auto-actions $main::secobj = Apache::RPC::Server->new(no_default => 1, path => '/rpc-secured');
# Imagine that add_method and/or add_methods_in_dir has been used to # add to the methods tables for those objects. Now assign them to # locations managed by Apache: $Location{'/RPC'} = { SetHandler => 'perl-script', PerlHandler => '$main::defobj' }; $Location{'/rpc-secure'} = { SetHandler => 'perl-script', PerlHandler => '$main::secobj', AuthUserFile => '/etc/some_file', AuthType => 'Basic', AuthName => 'SecuredRPC', 'require' => 'valid-user' };
</Perl>
Note that the assignment of the PerlHandler
value was a string
representation of the object reference itself. mod_perl performs a sort of
``thaw'' of this string when the location is accessed. Since this class
implements itself as a method handler, this causes the handler()
method
for each of the locations to be handed the Apache::RPC::Server object
directly. Note also that the value assigned to PerlHandler
cannot be a
lexical variable, or it will be out of scope when the handler is called.
All methods return some type of reference on success, or an error string on failure. Non-reference return values should always be interpreted as errors unless otherwise noted.
Where appropriate, the log_error
method from the Apache package
is called to note internal errors.
This began as a reference implementation in which clarity of process and readability of the code took precedence over general efficiency. It is now being maintained as production code, but may still have parts that could be written more efficiently.
Please report any bugs or feature requests to
bug-rpc-xml at rt.cpan.org
, or through the web interface at
http://rt.cpan.org/NoAuth/ReportBug.html. I will be
notified, and then you'll automatically be notified of progress on
your bug as I make changes.
This file and the code within are copyright (c) 2011 by Randy J. Ray.
Copying and distribution are permitted under the terms of the Artistic License 2.0 (http://www.opensource.org/licenses/artistic-license-2.0.php) or the GNU LGPL 2.1 (http://www.opensource.org/licenses/lgpl-2.1.php).
The XML-RPC standard is Copyright (c) 1998-2001, UserLand Software, Inc. See <http://www.xmlrpc.com> for more information about the XML-RPC specification.
Randy J. Ray <rjray@blackperl.com>
Apache::RPC::Server - A subclass of RPC::XML::Server tuned for mod_perl |