[Zope] XML-RPC and binary data
Casey Duncan
casey@zope.com
Tue, 10 Sep 2002 10:53:18 -0400
This would appear to be a bug. I would file a collector issue re this.=20
-Casey
On Monday 09 September 2002 03:32 pm, Kyler Laird wrote:
> [I'm copying this to the Zope list so that someone there
> will be sure to correct any gross mistakes I make.]
>=20
> Transfering binary data through XML-RPC does not seem to
> be the problem that you described. xmlrpclib handles it
> fine. Zope receives it fine. It's just unusable once
> it gets to Zope.
>=20
> As a test, I created a script that made a Binary object
> from a simple image
> =09foo =3D xmlrpclib.Binary(img.read())
> and then called a test script on my Zope server.
> =09result =3D Zopesvr.test.xmlrpc(foo)
> This worked o.k. When I printed the string rendition of
> what the script received, I got
> =09<xmlrpclib.Binary instance at 0x98420b4>
>=20
> Looks good, no? This is much better than we'd thought;
> there is no need to manually base64 encode it on the
> client.
>=20
> However...it turns out that the Binary class in Zope's
> xmlrpclib product is quite a kludge.
> =09#
> =09# binary data wrapper (NOTE: this is an extension to Userland's
> =09# XML-RPC protocol! only for use with compatible servers!)
> =09
> =09class Binary:
> =09
> =09 def __init__(self, data=3DNone):
> =09 self.data =3D data
> =09
> =09 def decode(self, data):
> =09 import base64
> =09 self.data =3D base64.decodestring(data)
> =09
> =09 def encode(self, out):
> =09 import base64, StringIO
> =09 out.write("<value><base64>\n")
> =09 base64.encode(StringIO.StringIO(self.data), out)
> =09 out.write("</base64></value>\n")
>=20
> The first thing to notice is that we don't know what type
> of data is in a Binary object. You just initialize it
> with some data and then you either encode() or decode() it.
> If it was initialized with encoded data and you encode() it
> or it was initialized with decoded data and you decode() it,
> you'll probably not get what you expected.
>=20
> The more important deficiency in this class is that even if
> you do figure out what kind of data is in there, there's no
> way for you (as a normal user) to get at it. Both decode()
> and encode() want to stuff their results in a file object.
> I do not know of any way you can get one in Zope. It does
> not matter though - you are not allowed to access them
> anyway.
>=20
> So...you're screwed. You can't touch the data. (No, you
> can't just use a Binary object with manage_addFile.)
>=20
> The quick and dirty solution is to add
> =09import AccessControl
> =09AccessControl.allow_class(Binary)
> to xmlrpclib.py. Then you can get straight at the "data"
> of the Binary object. (I just did this and passed it to
> manage_addImage(). It worked fine. The data was already
> decoded.)
>=20
> Ideally, you'd add some sane public methods to the Binary
> class. Perhaps "encoded()" and "decoded()" would be a
> place to start. They could return either strings or
> StringIO objects.
>=20
> Sorry I don't have a better solution, but it looks like
> you're probably going to have to patch Zope if you don't
> want to give up on XML-RPC and just use HTTP POST. I
> appreciate and share your desire to use XML-RPC with Zope,
> but until we get Binary straightened out in Zope and basic
> authentication added in Python, it just takes too many
> kludges to recommend.
>=20
> --kyler
>=20
>=20
> _______________________________________________
> Zope maillist - Zope@zope.org
> http://lists.zope.org/mailman/listinfo/zope
> ** No cross posts or HTML encoding! **
> (Related lists -=20
> http://lists.zope.org/mailman/listinfo/zope-announce
> http://lists.zope.org/mailman/listinfo/zope-dev )
>=20