Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

XML-RPC in a CGI::Application

by jaldhar (Vicar)
on Aug 31, 2004 at 05:17 UTC ( #387106=sourcecode: print w/ replies, xml ) Need Help??

Category: CGI Programming
Author/Contact Info Jaldhar H. Vyas <jaldhar@braincells.com>
Description:

While a traditional CGI program is a good way for users to interact with your website, they include a lot of extra interface simply to accomodate human frailties. A web service on the other hand is designed to provide programs with access to the functionality of your site with as little overhead as possible.

You don't have to choose between the two. In this example I show you how to implement both CGI and XML-RPC access to a single script. It uses Frontier::RPC HTML::Template and CGI::Application and provides the ability to get the square of a number you input. It has four files:

  • An XML-RPC client you can run from the command line.
  • A subclass of CGI::Application called Square.pm
  • A driver script called index.cgi which uses Square.pm
  • An HTML::Template called view used by Square.pm

Put these files into a subdirectory called square off the root directory of your webserver. You can call the script as a CGI by accessing http://localhost/square/index.cgi or as an XML-RPC based web service by using the client program.

This is the XML-RPC client.

#!/usr/bin/perl
use strict;
use warnings;
use Frontier::Client;

my $number;

{
  print "Enter a number\n";
  $number = <STDIN>;
  chomp($number);
  redo unless $number =~ /^\d+$/;
}

my $server_url = 'http://localhost/square/index.cgi/RPC2';
my $server = Frontier::Client->new(url => $server_url);

my $result = $server->call('sample.square', $number);
my $square = $result->{'square'};
my $difference = $result->{'difference'};

print "The square of $number is $square.\n";

This is the CGI::Application subclass which implements the functionality of the server.

package Square;
use base 'CGI::Application';

sub setup
{
  my ($self) = @_;

  $ENV{'PATH'} = '';

  my @pi = split(m{/}, $self->query->path_info());
  $self->start_mode(($pi[1] eq 'RPC2') ? 'RPC2' : 'view');
  $self->run_modes(
    'view'   => 'view',
    'RPC2'   => 'rpc2',
  );
}

sub view
{
  my ($self) = @_;

  my $number = $self->query->param('number');
  my $template = $self->load_tmpl('view');
  $template->param(NUMBER => $number,
                   SQUARE => square($number)->{square},
  );
  return $template->output;
}

sub rpc2
{
  my ($self) = @_;

  require Frontier::RPC2;

  my $rpc = Frontier::RPC2->new();
  my $response = $rpc->serve($self->query->param('POSTDATA'),
    {
      'sample.square' => \&square,
    },
  );

  $self->header_props( -type => 'text/xml', charset => 'UTF-8', );
  return $response;
}

sub square
{
  my ($x) = @_;

  return {square => ($x ** 2)};
}

1;

Here is the driver script that uses the above module:

#!/usr/bin/perl -T
use warnings;
use strict;
use lib '.';
use Square;

my $square = Square->new();
$square->run();

Here is the HTML::Template used in the view run mode.

<html>
  <head>
    <title>Square Two Numbers</title>
  </head>
  <body>
    <h1>Square Two Numbers</h1>
    <form action="http://localhost/square/index.cgi/view" method="POST
+">
    Enter a number: <input type="text" name="number">
    <input type="submit">
    </form>
    <!-- TMPL_IF NAME="number" -->
       <p>The square of <!-- TMPL_VAR NAME="number" --> is <!-- TMPL_V
+AR NAME="square" -->.</p>
    <!-- /TMPL_IF -->
  </body>
</html>

Comment on XML-RPC in a CGI::Application
Select or Download Code

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://387106]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (12)
As of 2014-07-28 17:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (204 votes), past polls