RPC-XML

 view release on metacpan or  search on metacpan

lib/RPC/XML/Server.pm  view on Meta::CPAN

#
#   Libraries:      HTTP::Daemon (conditionally)
#                   HTTP::Response
#                   HTTP::Status
#                   URI
#                   Scalar::Util
#                   RPC::XML
#                   RPC::XML::ParserFactory
#                   RPC::XML::Procedure
#                   Compress::Raw::Zlib is used if available
#
#   Global Consts:  $VERSION
#                   $INSTALL_DIR
#                   %FAULT_TABLE
#
###############################################################################

package RPC::XML::Server;

use 5.008008;
use strict;
use warnings;
use vars qw($VERSION $INSTALL_DIR %FAULT_TABLE  @XPL_PATH %CLASS_MAP
            $IO_SOCKET_SSL_HACK_NEEDED $COMPRESSION_AVAILABLE);

use Carp qw(carp croak);
use File::Spec;
use File::Temp;
use IO::Handle;
use Module::Load;
use Scalar::Util 'blessed';

use HTTP::Status;
use HTTP::Response;
use URI;

use RPC::XML;
use RPC::XML::ParserFactory;
use RPC::XML::Procedure;

BEGIN
{
    $INSTALL_DIR =
        File::Spec->catpath((File::Spec->splitpath(__FILE__))[0, 1], q{});
    @XPL_PATH = ($INSTALL_DIR, File::Spec->curdir);

    # For now, I have an ugly hack in place to make the functionality that
    # runs under HTTP::Daemon/Net::Server work better with SSL. This flag
    # starts out true, then gets set to false the first time the hack is
    # applied, so that it doesn't get repeated over and over...
    $IO_SOCKET_SSL_HACK_NEEDED = 1;

    # Check for compression support
    $COMPRESSION_AVAILABLE =
        (eval { load Compress::Zlib; 1; }) ? 'deflate' : q{};

    # Set up the initial table of fault-types and their codes/messages
    %FAULT_TABLE = (
        badxml       => [ 100 => 'XML parse error: %s' ],
        badmethod    => [ 200 => 'Method lookup error: %s' ],
        badsignature => [ 201 => 'Method signature error: %s' ],
        execerror    => [ 300 => 'Code execution error: %s' ],
    );

    # This is used by add_method to map "types" to instantiation classes
    %CLASS_MAP = (
        method    => 'RPC::XML::Method',
        procedure => 'RPC::XML::Procedure',
        function  => 'RPC::XML::Function',
    );
}

$VERSION = '1.75';

###############################################################################
#
#   Sub Name:       new
#
#   Description:    Create a new RPC::XML::Server object. This entails getting
#                   a HTTP::Daemon object, saving several internal values, and
#                   other operations.
#
#   Arguments:      NAME      IN/OUT  TYPE      DESCRIPTION
#                   $class    in      scalar    Ref or string for the class
#                   %args     in      hash      Additional arguments
#
#   Returns:        Success:    object reference
#                   Failure:    error string
#
###############################################################################
sub new ## no critic (ProhibitExcessComplexity)
{
    my ($class, %args) = @_;

    my (
        $self, $http, $resp, $host, $port, $queue, $URI, $srv_version,
        $srv_name
    );

    # Don't accept a blessed value for $class
    if (ref $class)
    {
        return __PACKAGE__ . '::new: Must be called as a static method';
    }

    $self = bless {}, $class;

    $srv_version = delete $args{server_version} || $self->version;
    $srv_name    = delete $args{server_name}    || $class;
    $self->{__server_token} = "$srv_name/$srv_version";

    if (delete $args{no_http})
    {
        $self->{__host} = delete $args{host} || q{};
        $self->{__port} = delete $args{port} || q{};
    }
    else
    {
        require HTTP::Daemon;

        $host  = delete $args{host}  || q{};

lib/RPC/XML/Server.pm  view on Meta::CPAN

            limitexceeded => [ 500 => 'Call limit exceeded' ],
            accessdenied  => [ 600 => 'Access denied: %s' ],
            serviceclosed => 700
        },
        ...
    );

In this example, the fault-type "limitexceeded" is defined as having a fault
code of 500 and a static message of C<Call limit exceeded>. The next fault
defined is "accessdenied", which has a code of 600 and message that starts
with C<Access denied:> and incorporates whatever message was passed in to the
fault creation. The last example defines a fault called C<serviceclosed> that
has a code of 700 and uses any passed-in message unaltered.

=head3 Server-defined faults

The B<RPC::XML::Server> class defines the following faults and uses them
internally. You can override the codes and messages for these by including them
in the table passed as a C<fault_table> argument. The faults fall into three
groups:

=over 4

=item Request Initialization

Faults in this group stem from the initialization of the request and the
parsing of the XML. The codes for this group fall in the range 100-199.

=item Method Resolution

This group covers problems with mapping the request to a known method or
function on the server. These codes will be in the range 200-299.

=item Execution

Lastly, these faults are for problems in actually executing the requested
code. Their codes are in the range 300-399.

=back

The faults, and the phases they apply to, are:

=over 4

=item badxml (Request Initialization)

This fault is sent back to the client when the XML of the request did not
parse as a valid XML-RPC request.

The code is C<100>, and the message is of the form, C<XML parse error: %s>.
The specific error from the XML parser is included in the message.

=item badmethod (Method Resolution)

This fault is sent when the requested method is unknown to the server. No
method has been configured on the server by that name.

The code is C<200>, and the message is of the form, C<Method lookup error: %s>.
The name of the method and other information is included in the message.

=item badsignature (Method Resolution)

If a method is known on the server, but there is no signature that matches the
sequence of arguments passed, this fault is returned. This fault cannot be
triggered by server-side code configured via B<RPC::XML::Function>, as no
signature-checking is done for those.

The code is C<201>, and the message is of the form, C<Method signature error:
%s>. The name of the method and the signature of the arguments is included in
the message.

=item execerror (Execution)

This fault relates back to the client any exception thrown by the remote code
during execution. If the invoked code returned their error in the form of a
B<RPC::XML::fault> object, that fault is returned instead. Otherwise, the
value of C<$@> is used in the message of the fault that gets generated.

The code is C<300>, and the message is of the form, C<Code execution error:
%s>. The actual text of the exception thrown is included in the message.

=back

There is one special server-fault whose code and message cannot be overridden.
If a call is made to B<server_fault> for an unknown type of fault, the
returned object will have a code of C<-1> and a message stating that the
fault-type is unknown. The message will include both the requested type-name
and any message (if any) that was passed in.

=head3 Adjusting the server-defined codes

If you just want to "move" the range of codes that the server uses out of the
way of your application's own faults, this can be done with the
C<fault_code_base> parameter when constructing the server object. The value
of the parameter must be an integer, and it is added to the value of all
existing fault codes. For example, a value of C<10000> would make the code
for the C<badxml> fault be C<10100>, the code for C<badmethod> be C<10200>,
etc.

This is applied before any user-defined faults are merged in, so their code
values will not be affected by this value.

=head1 DIAGNOSTICS

Unless explicitly stated otherwise, 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.

=head1 BUGS

Please report any bugs or feature requests to
C<bug-rpc-xml at rt.cpan.org>, or through the web interface at
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=RPC-XML>. I will be
notified, and then you'll automatically be notified of progress on
your bug as I make changes.

=head1 SUPPORT

=over 4

=item * RT: CPAN's request tracker



( run in 0.652 second using v1.01-cache-2.11-cpan-71847e10f99 )