This would appear to be a bug. I would file a collector issue re this. -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.]
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.
As a test, I created a script that made a Binary object from a simple image foo = xmlrpclib.Binary(img.read()) and then called a test script on my Zope server. result = Zopesvr.test.xmlrpc(foo) This worked o.k. When I printed the string rendition of what the script received, I got <xmlrpclib.Binary instance at 0x98420b4>
Looks good, no? This is much better than we'd thought; there is no need to manually base64 encode it on the client.
However...it turns out that the Binary class in Zope's xmlrpclib product is quite a kludge. # # binary data wrapper (NOTE: this is an extension to Userland's # XML-RPC protocol! only for use with compatible servers!)
class Binary:
def __init__(self, data=None): self.data = data
def decode(self, data): import base64 self.data = base64.decodestring(data)
def encode(self, out): import base64, StringIO out.write("<value><base64>\n") base64.encode(StringIO.StringIO(self.data), out) out.write("</base64></value>\n")
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.
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.
So...you're screwed. You can't touch the data. (No, you can't just use a Binary object with manage_addFile.)
The quick and dirty solution is to add import AccessControl AccessControl.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.)
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.
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.
--kyler
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )