use
5.006000;
m{
};
our
$VERSION
=
'0.05'
;
sub
ua {
shift
->{ua} }
sub
encoder {
shift
->{encoder} }
sub
new {
my
$pkg
=
shift
;
my
$self
=
bless
{},
$pkg
;
$self
->init(
@_
);
$self
->components;
$self
;
}
sub
init {
my
$self
=
shift
;
local
$SIG
{__WARN__} =
sub
{
local
$_
=
shift
; s{\n$}{};carp
$_
};
my
%args
= (
base
=>
'/'
,
@_
);
@$self
{
keys
%args
} =
values
%args
;
$self
->{
$_
} or croak
"$_ not defined"
for
qw(host)
;
$self
->{useragent} ||=
'AnyEvent::RPC/'
.
$AnyEvent::RPC::VERSION
;
return
;
}
sub
components {
my
$self
=
shift
;
my
$package
=
ref
$self
;
unless
(
ref
$self
->{encoder} ) {
$self
->{encoder} =
$self
->_load(
'::Enc'
,
$self
->{encoder},
'REST'
,
debug
=>
$self
->{debug},
);
}
unless
(
ref
$self
->{ua} ) {
$self
->{ua} =
$self
->_load(
'::UA'
,
$self
->{ua},
''
,
ua
=>
$self
->{useragent} ||
$package
.
'/'
.(
do
{
no
strict
'refs'
; ${
$package
.
'::VERSION'
} } ||
$VERSION
),
timeout
=>
$self
->{timeout},
debug
=>
$self
->{debug},
);
}
return
;
}
sub
_load {
my
$pkg
=
shift
;
my
(
$suffix
,
$req
,
$default
,
@args
) =
@_
;
my
$prefix
= __PACKAGE__.
$suffix
;
if
(
defined
$req
) {
$req
=~ s{^\+}{} or
$req
=
$prefix
.
'::'
.
$req
;
}
else
{
$req
=
$prefix
.(
$default
?
'::'
.
$default
:
''
);
}
eval
{
$req
->can(
'new'
)
or
require
join
'/'
,
split
'::'
,
$req
.
'.pm'
;
1;
}
or
do
{
croak
"Can't load $req: $@\n"
;
};
return
$req
->new(
@args
) or croak
"$req not created"
;
}
sub
req {
my
$self
=
shift
;
my
%args
=
@_
;
croak(
"req have no cb and useragent is async"
)
unless
$args
{cb};
my
%req
=
$self
->encoder->request(
$self
,
%args
);
my
@data
;
$self
->ua->call(
(
$args
{method} ||
$req
{method} ||
'POST'
) =>
$req
{uri},
headers
=> {
exists
$req
{headers} ? ( %{
$req
{headers}} ) : (),
exists
$args
{headers} ? ( %{
$args
{headers}} ) : (),
},
exists
$req
{body} ? (
body
=>
$req
{body}) : (),
cb
=>
sub
{
my
$res
=
shift
;
my
@rv
=
$self
->encoder->decode(
$self
,
$res
);
$args
{cb}(
@rv
);
return
;
my
@data
;
{
(
my
$status
=
$res
->status_line )=~ s/:?\s*$//s;
$res
->code == 200 or
@data
=
(rpcfault(
$res
->code,
"Call to $req{uri} failed: $status"
))
and
last
;
my
$text
=
$res
->content;
length
(
$text
) and
$text
=~ /^\s*<\?xml/s or
@data
=
({
fault
=>{
faultCode
=> 499,
faultString
=>
"Call to $req{uri} failed: Response is not an XML: \"$text\""
}})
and
last
;
eval
{
@data
=
$self
->encoder->decode(
$text
);
1;
} or
@data
=
({
fault
=>{
faultCode
=> 499,
faultString
=>
"Call to $req{uri} failed: Bad Response: $@, \"$text\""
}})
and
last
;
}
if
(
$args
{cb}) {{
$args
{cb}(
@data
);
return
;
}}
},
);
$args
{cb} and
defined
wantarray
and carp
"Useless use of return value for "
.__PACKAGE__.
"->call(cb)"
;
return
if
$args
{cb};
return
@data
== 1 ?
$data
[0] :
@data
;
}
1;