#!/usr/bin/perl -w
#
# Agent.pm - XPC Agent
#
# Copyright (C) 2001 Gregor N. Purdy.
# All rights reserved.
#
# This is free software; you can redistribute it and/or modify it under
# the same terms as Perl itself.
#
use strict;
package XPC::Agent;
use URI;
use LWP::UserAgent;
use HTTP::Request;
use XPC;
#
# new()
#
sub new
{
my $class = shift;
my $uri_input = shift;
my $self = bless { }, $class;
$self->{URI} = URI->new($uri_input);
$self->{DEBUG} = 0;
return $self;
}
#
# debug()
#
sub debug
{
my $self = shift;
$self->{DEBUG} = ($_[0] ? 1 : 0) if @_;
return $self->{DEBUG};
}
#
# uri()
#
sub uri
{
my $self = shift;
return $self->{URI};
}
#
# _call_()
#
sub _call_
{
my ($self, $procedure, @args) = @_;
#
# Request Building:
#
print "$0: Building XPC request...\n" if $self->debug();
my $uri_string = $self->uri->as_string;
my $xpc_req = XPC->new_call($procedure);
my $xpc_string = $xpc_req->as_string;
if ($self->debug()) {
print "XPC REQUEST:\n";
print $xpc_string;
print "\n\n";
}
print "$0: Building HTTP request 'POST => $uri_string'...\n" if $self->debug();
my $http_req = HTTP::Request->new('POST', $uri_string);
print "$0: Adding XPC content...\n" if $self->debug();
$http_req->content($xpc_string);
if ($self->debug()) {
print "HTTP REQUEST:\n";
print $http_req->as_string;
print "\n\n";
}
#
# Sending Request:
#
my $ua = LWP::UserAgent->new;
my $http_res = $ua->request($http_req);
#
# Response Processing:
#
if ($self->debug()) {
print "HTTP RESPONSE:\n";
print $http_res->as_string;
print "\n\n";
}
if ($http_res->code != 200) {
die "XPC::Agent::_call_(): Server did not return status 200!\n";
}
my $xpc_res = XPC->new($http_res->content);
$xpc_res = $xpc_res->[0];
if ($xpc_res->faults) {
my $fault = $xpc_res->fault(0);
die "XPC::Agent::_call_(): Detected fault presence but can't find it!\n" unless defined $fault;
my $code = $fault->code;
my $message = $fault->message;
die "Fault [$code]: $message\n";
} else {
my $result = $xpc_res->result(0);
return $result->value;
}
}
#
# AUTOLOAD()
#
use vars qw($AUTOLOAD);
sub AUTOLOAD
{
my ($self, @args) = @_;
return if $AUTOLOAD eq 'XPC::Agent::DESTROY';
my $procedure = $AUTOLOAD;
$procedure =~ s/^XPC::Agent:://;
print "Calling procedure '$procedure'...\n" if $self->debug();
return $self->_call_($procedure, @args);
}
1;
=head1 NAME
XPC::Agent - XML Procedure Call client
=head1 SYNOPSIS
use XPC::Agent;
my $agent = XPC::Agent->new($server_url);
printf "localtime() --> %s\n", $agent->localtime();
=head1 DESCRIPTION
Uses Perl's AUTOLOAD mechanism to intercept calls to undefined subroutines
and forward them via XPC over HTTP to a server.
=head1 AUTHOR
Gregor N. Purdy E<lt>gregor@focusresearch.comE<gt>
=head1 COPYRIGHT
Copyright (C) 2001 Gregor N. Purdy.
All rights reserved.
This is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
syntax highlighted by Code2HTML, v. 0.9.1