File Coverage

blib/lib/Frontier/Client.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             #
2             # Copyright (C) 1998 Ken MacLeod
3             # Frontier::Client is free software; you can redistribute it
4             # and/or modify it under the same terms as Perl itself.
5             #
6             # $Id: Client.pm,v 1.8 2001/10/03 01:30:54 kmacleod Exp $
7             #
8              
9             # NOTE: see Net::pRPC for a Perl RPC implementation
10              
11 1     1   606 use strict;
  1         2  
  1         47  
12              
13             package Frontier::Client;
14 1     1   566 use Frontier::RPC2;
  0            
  0            
15             use LWP::UserAgent;
16             use HTTP::Request;
17              
18             use vars qw{$AUTOLOAD};
19              
20             sub new {
21             my $class = shift;
22             my $self = ($#_ == 0) ? { %{ (shift) } } : { @_ };
23              
24             bless $self, $class;
25              
26             die "Frontier::RPC::new: no url defined\n"
27             if !defined $self->{'url'};
28              
29             $self->{'ua'} = LWP::UserAgent->new;
30             $self->{'ua'}->proxy('http', $self->{'proxy'})
31             if(defined $self->{'proxy'});
32             $self->{'rq'} = HTTP::Request->new (POST => $self->{'url'});
33             $self->{'rq'}->header('Content-Type' => 'text/xml');
34              
35             my @options;
36              
37             if(defined $self->{'encoding'}) {
38             push @options, 'encoding' => $self->{'encoding'};
39             }
40              
41             if (defined $self->{'use_objects'} && $self->{'use_objects'}) {
42             push @options, 'use_objects' => $self->{'use_objects'};
43             }
44              
45             $self->{'enc'} = Frontier::RPC2->new(@options);
46              
47             return $self;
48             }
49              
50             sub call {
51             my $self = shift;
52              
53             my $text = $self->{'enc'}->encode_call(@_);
54              
55             if ($self->{'debug'}) {
56             print "---- request ----\n";
57             print $text;
58             }
59              
60             $self->{'rq'}->content($text);
61              
62             my $response = $self->{'ua'}->request($self->{'rq'});
63              
64             if (!$response->is_success) {
65             die $response->status_line . "\n";
66             }
67              
68             my $content = $response->content;
69              
70             if ($self->{'debug'}) {
71             print "---- response ----\n";
72             print $content;
73             }
74              
75             my $result = $self->{'enc'}->decode($content);
76              
77             if ($result->{'type'} eq 'fault') {
78             die "Fault returned from XML RPC Server, fault code " . $result->{'value'}[0]{'faultCode'} . ": "
79             . $result->{'value'}[0]{'faultString'} . "\n";
80             }
81              
82             return $result->{'value'}[0];
83             }
84              
85             # shortcuts
86             sub base64 {
87             my $self = shift;
88              
89             return Frontier::RPC2::Base64->new(@_);
90             }
91              
92             sub boolean {
93             my $self = shift;
94              
95             return Frontier::RPC2::Boolean->new(@_);
96             }
97              
98             sub double {
99             my $self = shift;
100              
101             return Frontier::RPC2::Double->new(@_);
102             }
103              
104             sub int {
105             my $self = shift;
106              
107             return Frontier::RPC2::Integer->new(@_);
108             }
109              
110             sub string {
111             my $self = shift;
112              
113             return Frontier::RPC2::String->new(@_);
114             }
115              
116             sub date_time {
117             my $self = shift;
118              
119             return Frontier::RPC2::DateTime::ISO8601->new(@_);
120             }
121              
122             # something like this could be used to get an effect of
123             #
124             # $server->examples_getStateName(41)
125             #
126             # instead of
127             #
128             # $server->call('examples.getStateName', 41)
129             #
130             # for Frontier's
131             #
132             # [server].examples.getStateName 41
133             #
134             # sub AUTOLOAD {
135             # my ($pkg, $method) = ($AUTOLOAD =~ m/^(.*::)(.*)$/);
136             # return if $method eq 'DESTROY';
137             #
138             # $method =~ s/__/=/g;
139             # $method =~ tr/_=/._/;
140             #
141             # splice(@_, 1, 0, $method);
142             #
143             # goto &call;
144             # }
145              
146             =head1 NAME
147              
148             Frontier::Client - issue Frontier XML RPC requests to a server
149              
150             =head1 SYNOPSIS
151              
152             use Frontier::Client;
153              
154             $server = Frontier::Client->new( I<OPTIONS> );
155              
156             $result = $server->call($method, @args);
157              
158             $boolean = $server->boolean($value);
159             $date_time = $server->date_time($value);
160             $base64 = $server->base64($value);
161              
162             $value = $boolean->value;
163             $value = $date_time->value;
164             $value = $base64->value;
165              
166             =head1 DESCRIPTION
167              
168             I<Frontier::Client> is an XML-RPC client over HTTP.
169             I<Frontier::Client> instances are used to make calls to XML-RPC
170             servers and as shortcuts for creating XML-RPC special data types.
171              
172             =head1 METHODS
173              
174             =over 4
175              
176             =item new( I<OPTIONS> )
177              
178             Returns a new instance of I<Frontier::Client> and associates it with
179             an XML-RPC server at a URL. I<OPTIONS> may be a list of key, value
180             pairs or a hash containing the following parameters:
181              
182             =over 4
183              
184             =item url
185              
186             The URL of the server. This parameter is required. For example:
187              
188             $server = Frontier::Client->new( 'url' => 'http://betty.userland.com/RPC2' );
189              
190             =item proxy
191              
192             A URL of a proxy to forward XML-RPC calls through.
193              
194             =item encoding
195              
196             The XML encoding to be specified in the XML declaration of outgoing
197             RPC requests. Incoming results may have a different encoding
198             specified; XML::Parser will convert incoming data to UTF-8. The
199             default outgoing encoding is none, which uses XML 1.0's default of
200             UTF-8. For example:
201              
202             $server = Frontier::Client->new( 'url' => 'http://betty.userland.com/RPC2',
203             'encoding' => 'ISO-8859-1' );
204              
205             =item use_objects
206              
207             If set to a non-zero value will convert incoming E<lt>i4E<gt>,
208             E<lt>floatE<gt>, and E<lt>stringE<gt> values to objects instead of
209             scalars. See int(), float(), and string() below for more details.
210              
211             =item debug
212              
213             If set to a non-zero value will print the encoded XML request and the
214             XML response received.
215              
216             =back
217              
218             =item call($method, @args)
219              
220             Forward a procedure call to the server, either returning the value
221             returned by the procedure or failing with exception. `C<$method>' is
222             the name of the server method, and `C<@args>' is a list of arguments
223             to pass. Arguments may be Perl hashes, arrays, scalar values, or the
224             XML-RPC special data types below.
225              
226             =item boolean( $value )
227              
228             =item date_time( $value )
229              
230             =item base64( $base64 )
231              
232             The methods `C<boolean()>', `C<date_time()>', and `C<base64()>' create
233             and return XML-RPC-specific datatypes that can be passed to
234             `C<call()>'. Results from servers may also contain these datatypes.
235             The corresponding package names (for use with `C<ref()>', for example)
236             are `C<Frontier::RPC2::Boolean>',
237             `C<Frontier::RPC2::DateTime::ISO8601>', and
238             `C<Frontier::RPC2::Base64>'.
239              
240             The value of boolean, date/time, and base64 data can be set or
241             returned using the `C<value()>' method. For example:
242              
243             # To set a value:
244             $a_boolean->value(1);
245              
246             # To retrieve a value
247             $base64 = $base64_xml_rpc_data->value();
248              
249             Note: `C<base64()>' does I<not> encode or decode base64 data for you,
250             you must use MIME::Base64 or similar module for that.
251              
252             =item int( 42 );
253              
254             =item float( 3.14159 );
255              
256             =item string( "Foo" );
257              
258             By default, you may pass ordinary Perl values (scalars) to be encoded.
259             RPC2 automatically converts them to XML-RPC types if they look like an
260             integer, float, or as a string. This assumption causes problems when
261             you want to pass a string that looks like "0096", RPC2 will convert
262             that to an E<lt>i4E<gt> because it looks like an integer. With these
263             methods, you could now create a string object like this:
264              
265             $part_num = $server->string("0096");
266              
267             and be confident that it will be passed as an XML-RPC string. You can
268             change and retrieve values from objects using value() as described
269             above.
270              
271             =back
272              
273             =head1 SEE ALSO
274              
275             perl(1), Frontier::RPC2(3)
276              
277             <http://www.scripting.com/frontier5/xml/code/rpc.html>
278              
279             =head1 AUTHOR
280              
281             Ken MacLeod <ken@bitsko.slc.ut.us>
282              
283             =cut
284              
285             1;