Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

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 <>

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
  • A driver script called index.cgi which uses
  • An HTML::Template called view used by

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.

use strict;
use warnings;
use Frontier::Client;

my $number;

  print "Enter a number\n";
  $number = <STDIN>;
  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');
    '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)};


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();

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

    <title>Square Two Numbers</title>
    <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">
    <!-- TMPL_IF NAME="number" -->
       <p>The square of <!-- TMPL_VAR NAME="number" --> is <!-- TMPL_V
+AR NAME="square" -->.</p>
    <!-- /TMPL_IF -->

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2022-08-13 21:40 GMT
Find Nodes?
    Voting Booth?

    No recent polls found