# In the start-up Perl file:
use Apache::RPC::Server;
DESCRIPTION
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.
USAGE
This module is designed to be dropped in with little (if any) modification.
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.
Methods
In addition to inheriting all the methods from RPC::XML::Server, the
following methods are either added or overloaded by Apache::RPC::Server:
handler
This is the default content-handler routine that mod_perl expects when the
module is defined as managing the specified location. This is provided as a
method handler, meaning that the first argument is either an object
reference or a static string with the class name. This allows for other
packages to easily subclass 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.
init_handler
This is another Apache-level handler, this one designed for installation as a
"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)
This is the class constructor. It calls the superclass "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
The value associated with this key is a reference to an Apache request
object. If this is not passed, then it is assumed that this is being called in
the start-up phase of the server and the value returned from "Apache-"server>
(see Apache) is used.
server_id
This provides the server ID string for the RPC server (not to be confused with
the Apache server) that is being configured.
prefix
The prefix is used in retrieving certain configuration settings from the Apache
configuration file.
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])
This method is very similar to the "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)
Get the server object that corresponds to the argument passed. If the argument
is a reference to an Apache request object, use it to determine the name
(by path, etc.) and return that object. If the parameter is not a reference,
it is assumed to be the specific name desired.
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.
list_servers
Return a list of the names used for all the current server instances. Does
not return the server objects themselves (use get_server, above, for that).
version
This method behaves exactly like the RPC::XML::Server method, except that
the version string returned is specific to this module instead.
INSTALL_DIR
As with version, this is an overload of the parent-class static method that
returns the installation directory of this particular module.
Apache configuration semantics
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:
RPCOptPrefix [STRING]
Sets a prefix string to be applied to all of the following names before trying
to read their values. Useful for setting within a "<Location>" block
to ensure that no settings from a higher point in the hierarchy influence the
server being defined.
RpcServer [STRING]
Specify the name of the server to use for this location. If not passed, then
the default server is used. This server may also be explicitly requested by the
name """<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.
RpcMethodDir [DIRECTORY]
This variable specifies directories to be scanned for method "*.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.
RpcMethod [FILENAME]
This is akin to the directory-specification option above, but only provides a
single method at a time. It may also have multiple values separated by
colons. The method is loaded into the server table. If the name is not an
absolute pathname, then it is searched for in the directories that currently
comprise the path. The directories above, however, have not been added to the
search path yet. This is because these directives are processed immediately
after the directory specifications, and thus do not need to be searched. This
directive is designed to allow selective overriding of methods in the
previously-specified directories.
RpcDefMethods [YES|NO]
If specified and set to ``no'' (case-insensitive), suppresses the loading of the
system default methods that are provided with this package. The absence of this
setting is interpreted as a ``yes'', so explicitly specifying such is not needed.
RpcAutoMethods [YES|NO]
If specified and set to ``yes'', enables the automatic searching for a requested
remote method that is unknown to the server object handling the request. If
set to ``no'' (or not set at all), then a request for an unknown function causes
the object instance to report an error. If the routine is still not found, the
error is reported. Enabling this is a security risk, and should only be
permitted by a server administrator with fully informed acknowledgement and
consent.
RpcAutoUpdates [YES|NO]
If specified and set to ``yes'', enables the checking of the modification time
of the file from which a method was originally loaded. If the file has
changed, the method is re-loaded before execution is handed off. As with the
auto-loading of methods, this represents a potential security risk, and should
only be permitted by a server administrator with fully informed
acknowledgement and consent.
Specifying methods to the server(s)
Methods are provided to an Apache::RPC::Server object in three ways:
Default methods
Unless suppressed by a "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.
Configured directories
All method files (those ending in a suffix of "*.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.
By specific inclusion
Any methods specified directly by use of "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.
Usage Within <Perl> Sections
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:
(1)
The rpc-server object gets created in the master Apache process, rather than
within each child as a side-effect of the first request. Especially in cases
where there are going to be more than one server in use within the Apache
environment, this boosts performance by allowing newly-created children to
already have the server object and method table readily available.
(2)
It becomes possible to exert more detailed control over the creation and
configuration of each server object. Combining the get_method and
add_method operations permits ``sharing'' (of a sort) of methods between
server objects. Recall from the RPC::XML::Server documentation that, when a
method is invoked, the first argument is the server object that is marshalling
it.
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.
DIAGNOSTICS
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.
CAVEATS
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.
CREDITS
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.