Catalyst::Plugin::XMLRPC - DEPRECATED Dispatch XMLRPC methods with Catalyst


Catalyst-Plugin-XMLRPC documentation Contained in the Catalyst-Plugin-XMLRPC distribution.

Index


Code Index:

NAME

Top

Catalyst::Plugin::XMLRPC - DEPRECATED Dispatch XMLRPC methods with Catalyst

SYNOPSIS

Top

    # Include it in plugin list
    use Catalyst qw/XMLRPC/;

    # Public action to redispatch somewhere in a controller
    sub entrypoint : Global : Action('XMLRPC') {}

    # Methods with XMLRPC attribute in any controller
    sub echo : XMLRPC('myAPI.echo') {
        my ( $self, $c, @args ) = @_;
        return RPC::XML::fault->new( 400, "No input!" ) unless @args;
        return join ' ', @args;
    }

    sub add : XMLRPC {
        my ( $self, $c, $a, $b ) = @_;
        return $a + $b;
    }

DESCRIPTION

Top

This plugin is DEPRECATED. Please do not use in new code.

This plugin allows your controller class to dispatch XMLRPC methods from its own class.

METHODS

Top

$c->xmlrpc

Call this method from a controller action to set it up as a endpoint.

setup_dispatcher

SEE ALSO

Top

Catalyst::Manual, Catalyst::Test, Catalyst::Request, Catalyst::Response, Catalyst::Helper, RPC::XML

AUTHORS

Top

Sebastian Riedel, sri@oook.de Marcus Ramberg, mramberg@cpan.org Christian Hansen Yoshinori Sano Michiel Ootjers Jos Boumans

COPYRIGHT

Top

LICENSE

Top

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


Catalyst-Plugin-XMLRPC documentation Contained in the Catalyst-Plugin-XMLRPC distribution.
package Catalyst::Plugin::XMLRPC;

use strict;
use base 'Class::Data::Inheritable';
use attributes ();
use RPC::XML;
use RPC::XML::ParserFactory 'XML::Parser';
use Catalyst::Action;
use Catalyst::Utils;
use NEXT;

our $VERSION = '2.01';

__PACKAGE__->mk_classdata('_xmlrpc_parser');
__PACKAGE__->_xmlrpc_parser( RPC::XML::ParserFactory->new );

sub xmlrpc {
    my $c = shift;

    # Deserialize
    my $req;
    eval { $req = $c->_deserialize_xmlrpc };
    if ( $@ || !$req ) {
        $c->log->debug(qq/Invalid XMLRPC request "$@"/) if $c->debug;
        $c->_serialize_xmlrpc( RPC::XML::fault->new( -1, 'Invalid request' ) );
        return 0;
    }

    my $res = RPC::XML::fault->new( -2, "No response for request" );

    # We have a method
    my $method = $req->{method};
    $c->log->debug(qq/XMLRPC request for "$method"/) if $c->debug;

    if ($method) {

        my $container;
        for my $type ( @{ $c->dispatcher->dispatch_types } ) {
            $container = $type
              if $type->isa('Catalyst::Plugin::XMLRPC::DispatchType::XMLRPC');
        }

        if ($container) {
            if ( my $action = $container->{methods}{$method} ) {
                my $class = $action->class;
                $class = $c->components->{$class} || $class;
                my @args = @{ $c->req->args };
                $c->req->args( $req->{args} );
                $c->state( $c->execute( $class, $action ) );
                $res = $c->state;
                $c->req->args( \@args );
            }
            else { $res = RPC::XML::fault->new( -4, "Unknown method" ) }
        }
        else { $res = RPC::XML::fault->new( -3, "Please come back later" ) }

    }

    # Serialize response
    $c->_serialize_xmlrpc($res);
    return $res;
}

# Register our DispatchType
sub setup_dispatcher {
    my $c = shift;
    $c->NEXT::setup_dispatcher(@_);
    push @{ $c->dispatcher->preload_dispatch_types },
      '+Catalyst::Plugin::XMLRPC::DispatchType::XMLRPC';
    return $c;
}

# Deserializes the xml in $c->req->body
sub _deserialize_xmlrpc {
    my $c = shift;

    my $p       = $c->_xmlrpc_parser->parse;
    my $body    = $c->req->body;
    my $content = do { local $/; <$body> };
    $p->parse_more($content);
    my $req = $p->parse_done;

    my $name = $req->name;
    my @args = map { $_->value } @{ $req->args };

    return { method => $name, args => \@args };
}

# Serializes the response to $c->res->body
sub _serialize_xmlrpc {
    my ( $c, $status ) = @_;
    my $res = RPC::XML::response->new($status);
    $c->res->content_type('text/xml');
    $c->res->body( $res->as_string );
}

1;