Tuesday, June 07, 2005

Geeked out.

I spent the weekend up to my nuts in XML-RPC shenanigans. It took me about 4 hours to add a web service interface to the dodgy content management system I knocked up for my wife to use on our family website. The php xml-rpc library is great, and made the whole thing really straightforward.

Then I knocked up an applescript to allow us to upload an album of photos from iPhoto in one go. Previously we'd been uploading them one-by-one via a web page. Tedious. All was going well, until I got to the part where I needed to attach the image data to the xml-rpc request. In the php test client I'd written it was easy; read in the image as a string, and the php library would convert it to base64 and tag it as such in the xml. Bingo, Bob's yer uncle.

Applescript's xml-rpc support is provided through the Apple Event Manager which performs the translation between applescript data types and the xml equivalent. It should convert binary data into base64, same as the php library. I couldn't find any documentation that covered this, and even the internets were silent on the matter. So, I thought I'd better handle the conversion myself, via do shell script "openssl -enc base64". Which worked fine, but when the rpc call was made, the base64 data was passed as a string type, which the server wasn't happy with.

So, I tried coercing the base64 encoded data to the type class of "data". This was better. The server didn't complain about getting a string where it was expecting base64, but it didn't actually work. The base 64 element of the request looked like this <base64>++++++++++++</base64>. That's a bit wrong. For a 50k jpeg there should be about 100k's worth of base64 data, not a few '+' symbols. But I was on the right track - the type class of data was being tagged as base64.

Next step: maybe the AEM is trying to convert the already base64 encoded data to base64 for me, and ending up with rubbish. So I removed the step which called openssl, and replaced it with a open for access... read ... as data call, to get the raw image data to pass. Again the base64 tag was just a line of plusses. I tried reading in the image file as a type of "JPEG picture". No good. Passed as a parameter the JPEG picture's name gets passed as a string, instead of the image data as base64. Coerced to "data" and you get the line of plusses again.

So, I've learned that the AEM will pass objects of type class "data" tagged as base64 in the xml-rpc request. But I don't have a clue what it's actually converting them to. In the end I went back to encoding the image using openssl and passing it as a string. I changed the server-side php to take the data parameter as a string instead of base64, and handled the decoding by hand (via php's base64_decode function, which was handy).

It's a shame applescript's xml-rpc is broken in this regard, or at least not documented properly, because the rest of the xml-rpc support is excellent. It's pretty nifty that I managed to write in a few hours what I'd not managed to accomplish in weeks using a combination of applescript and the curl command.

That's enough geekery. My brain dump is complete. Hopefully that will save someone a lot of time when they try to base64-ify something in applescript. (Assuming google finds it here).

No comments:

Post a Comment