I've got XML data in AS3 that needs to be compressed, validated on my Java Google App Engine servlet then saved to a file in Google Cloud Storage. Later that file will be opened and decompressed by the AS3 client. The process works if I do it with plain XML or text, but if I ByteArray#compress the data, it dies during ByteArray#uncompress with "There was an error decompressing the data".
I've tried setting the content type and mime type at various points, as well as encoding with Base64, but every attempt seems to break in a different way and I never get the same XML back that I sent in. Do I need to use multipart? Should I compress on the server? What's the best practice for doing this?
Sending the data from AS3:
// compress xml using zlib
var xml:XML = <contents><thing>value</thing></contents>;
var bytes:ByteArray = new ByteArray();
bytes.writeObject(xml);
bytes.position = 0;
bytes.compress();
var request:URLRequest = new URLRequest(url);
var urlVariables :URLVariables = new URLVariables();
urlVariables.filename = "somefile.bin";
urlVariables.contents = bytes;
request.data = urlVariables;
request.method = URLRequestMethod.POST;
loader = new URLLoader();
loader.load(request);
Receiving it in the Java servlet and creating the file:
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String filename = req.getParameter("filename");
byte[] contents = req.getParameter("contents").getBytes();
GSFileOptionsBuilder optionsBuilder = new GSFileOptionsBuilder()
.setBucket("bucketname")
.setKey(filename)
.setAcl("public-read")
.setMimeType("binary/octet-stream");
AppEngineFile writableFile = fileService.createNewGSFile(optionsBuilder.build());
boolean lockForWrite = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(writableFile, lockForWrite);
writeChannel.write(ByteBuffer.wrap(contents));
writeChannel.closeFinally();
}
Opening the new file in AS3:
var url :String = "http://commondatastorage.googleapis.com/bucketname/somefile.bin";
var request:URLRequest = new URLRequest(url);
request.method = URLRequestMethod.GET;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(request);
protected function handleComplete (event:Event):void {
var bytes:ByteArray = new ByteArray();
bytes.writeObject(event.target.data);
// dies on this line with "There was an error decompressing the data."
bytes.uncompress();
var xml:XML = new XML(new String(bytes));
trace(xml);
}