jangidipramod / android-xmlrpc

Automatically exported from code.google.com/p/android-xmlrpc
0 stars 0 forks source link

Wrong XMLRPCCommon Object array serialization #41

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
If the serializeParams() method in XMLRPCCommon.java is given more than one 
parameter to serialize, the output is not strict to XMLRPC (though some client 
implementations e.g. Python xmlrpclib will still read it).
Each parameter is put into a separate <param> tag. However, only one <param> is 
allowed to occur in <params>

The output looks like:
<params>
  <param><value><i4>12</i4></value></param>
  <param><value><string>Egypt</string></value></param>
  <param><value><boolean>0</boolean></value></param>
  <param><value><i4>-31</i4></value></param>
</params>

The correct output would rather be:
<params>
  <param>
    <array>
      <data>
        <value><i4>12</i4></value>
        <value><string>Egypt</string></value>
        <value><boolean>0</boolean></value>
        <value><i4>-31</i4></value>
        </data>
    </array>
  </param>
</params>

The XMLRPCSerializer class can already generate this type of output. The only 
change required is for XMLRPCCommon.serializeParams(Object [] params) to not 
loop over each of the array entries and call the Serializer independently but 
to just give the array directly to the Serializer.

Original issue reported on code.google.com by f.metz...@gmail.com on 20 Aug 2012 at 9:19

GoogleCodeExporter commented 9 years ago
i don't understand to be honest: what do you want to do? are you working on 
client or server side?

Original comment by psk...@gmail.com on 22 Aug 2012 at 8:19

GoogleCodeExporter commented 9 years ago
I am using the XMLRPCServer and i am responding to a XMLRPC call with an 
Object[] (that contains more than one Object). 
But the existing code serializes each of the Objects in the array into its own 
<param></param> tag pair. This is not allowed by the specification. 
In this case, the response must be a single param tag which encloses 
<array><data></data></array> which in turn contains the individual return 
<value>s.

Original comment by f.metz...@gmail.com on 22 Aug 2012 at 11:24

GoogleCodeExporter commented 9 years ago
you are right: server part was done by some other guy and i don't why he 
created XMLRPCServer response method as:

public void respond(Socket socket, Object[] params) throws IOException

while it really should be:

public void respond(Socket socket, Object value) throws IOException

can you confirm it works as expected?

fixed in rev r30

Original comment by psk...@gmail.com on 22 Aug 2012 at 12:31

GoogleCodeExporter commented 9 years ago
There is still something missing in XMLRPCCommon. The varargs parameter of 
serializeParams(Object... params) is again just autoboxed into an Object[], 
which the method would loop over and put every Object in the array in a 
separate <param></param>.
Instead, you could remove the for-loop and give the array directly to the 
serializer.
Maybe something like this:

    protected void serializeParams(Object... params) throws IllegalArgumentException, IllegalStateException, IOException {
        if (params != null && params.length != 0)
        {
            serializer.startTag(null, Tag.PARAMS);
            serializer.startTag(null, Tag.PARAM).startTag(null, IXMLRPCSerializer.TAG_VALUE);
            if (params.length > 1)
                iXMLRPCSerializer.serialize(serializer, params);
            else
                iXMLRPCSerializer.serialize(serializer, params[0]);
            serializer.endTag(null, IXMLRPCSerializer.TAG_VALUE).endTag(null, Tag.PARAM);
            serializer.endTag(null, Tag.PARAMS);
        }
        }

Original comment by f.metz...@gmail.com on 23 Aug 2012 at 7:58

GoogleCodeExporter commented 9 years ago
could you please post your server code? at least that part that uses respond() 
method?

Original comment by psk...@gmail.com on 23 Aug 2012 at 8:10

GoogleCodeExporter commented 9 years ago
You can take a look at my github repo. The xmlrpcserver.respond is called in 
[1] but uses reflection to construct the respond parameters. So i am relying on 
the server code to do the right thing.

[1] 
https://github.com/fmetzger/android-seattle-sensors/blob/master/SeattleSensors/s
rc/at/univie/seattlesensors/XMLRPCSensorServerThread.java

Original comment by f.metz...@gmail.com on 24 Aug 2012 at 7:00

GoogleCodeExporter commented 9 years ago
note i had to change "respond" method signature from:
public void respond(Socket socket, Object[] params) throws IOException

to:
public void respond(Socket socket, Object value) throws IOException

i know its very bad idea to change an existing API but original author of this 
code made a mistake about returning multiple <param> tags inside <params> tag

that's why i think he used Object[] to represend multiple <param> tags, but as 
you pointed out only one <param> is allowed within <params> tag and that's why 
i changed Object[] to Object

see 
http://code.google.com/p/android-xmlrpc/source/browse/trunk/XMLRPC/src/org/xmlrp
c/XMLRPCServerTest.java?spec=svn30&r=30 

i added method "test" that returns an array of different values and it worked 
ok when i tested it

Original comment by psk...@gmail.com on 24 Aug 2012 at 9:44

GoogleCodeExporter commented 9 years ago
After removing all the Object[] encapsulations from my code, everything seems 
to work as expected now.
Thanks again for your support.

Original comment by f.metz...@gmail.com on 24 Aug 2012 at 12:36

GoogleCodeExporter commented 9 years ago
glad to hear everything works ok, btw you probably forgot to change the 
response of the method "isSeattleSensor"

Original comment by psk...@gmail.com on 25 Aug 2012 at 1:42