Dave, yep, that fixed it. But now that I can actually make rpc calls,
I've run into some other issues.
The server messes up whenever it needs to return any string (including
lists) with whitespace in it - it returns only the last non-whitspace
item. Is this a bug?
It also doesn't play nice with using the optional parameters of
ad_proc. The following code fails in xmlrpc_construct
with the error: no value for option "abc" (see below for
my test proc):
[xmlrpc_call $url bb_rpc_string -quotes_p 1 abc]
Also, the
XML-RPC spec.
defines scalars (of different types), structs, and arrays. Structs
have key value pairs like Tcl arrays and do not preserve order, but
(unlike Tcl arrays) struct values may themselves be scalars, structs,
or arrays. Arrays contain values only (not key value pairs), and each
value may be also be a scalar, struct, or array. I assume arrays
preserve order, although the spec. doesn't say.
So, I guess Tcl arrays should be represented as XML-RPC structs, and
Tcl lists could be represented by either scalar strings or XML-RPC
arrays. If the client and server are both using Tcl, I just using the
Tcl string representation of lists might be most convenient, but
XML-RPC arrays would be correct cross-language way to represent lists.
I don't think ns_xmlrpc is attempting to do any magic to automatically
convert Tcl data structures to XML-RPC data structures. So, I assume
I'm supposed to write a wrapper around each of my procedures to do
these data structure conversions for me? Are there any good examples
somewhere of doing that?
validator.tcl has a lot of stuff like this:
set struct(times10) [expr $number * 10]
return "-struct [list [array get struct]]"
And it looks to me like the xmlrpc_construct proc expects to get all
data as a Tcl list containing values, plus those little "what type of
data structure or scalar value is this?" prefix tags, like
-struct,
-array, or
-date.
So, am I on the right track here? I have to write wrappers that
explicitly specify all my data types in XML-RPC terms? Has anyone
considered or tried having ns_xmlrpc automagically convert Tcl to
XML-RPC data structures and back, instead?
Here are some examples showing the whitespace and parsing of '-' (like
in ad_proc) bugs:
ad_proc bb_rpc_list_1 {{}} {} {
return [list a b c d]
}
ad_proc bb_rpc_list_2 {{}} {} {
return ""[list a b c d]""
}
ad_proc bb_rpc_string_1 {{}} {} {
return {"a b c d"}
}
ad_proc bb_rpc_string_2 {{}} {} {
return {a b c d}
}
ad_proc bb_rpc_string {{
-quotes_p 0
} str } {} {
if { $quotes_p } {
return ""$str""
} else {
return $str
}
}
append body "
local: [bb_rpc_list_1] remote: [xmlrpc_call $url bb_rpc_list_1]
local: [bb_rpc_list_2] remote: [xmlrpc_call $url bb_rpc_list_2]
local: [bb_rpc_string_1] remote: [xmlrpc_call $url bb_rpc_string_1]
local: [bb_rpc_string_2] remote: [xmlrpc_call $url bb_rpc_string_2]
local: [bb_rpc_string {a b c}] remote: [xmlrpc_call $url bb_rpc_string {a b c}]
local: [bb_rpc_string {abc}] remote: [xmlrpc_call $url bb_rpc_string {abc}]
local: [bb_rpc_string -quotes_p 1 {abc}] remote: FAILS
"
## Fails in xmlrpc_construct with: no value for option "abc"
#[xmlrpc_call $url bb_rpc_string -quotes_p 1 {abc}]
ns_return 200 text/plain $body
And here are my results from the commands immediately above:
local: a b c d remote: d
local: "a b c d" remote: a b c d
local: "a b c d" remote: a b c d
local: a b c d remote: d
local: a b c remote: c
local: abc remote: abc
local: "abc" remote: FAILS