title: How to send binary data from AS3 through Java to a filesystem?
body: <p>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". </p>
  
  <p>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?</p>
  
  <p>Sending the data from AS3:</p>
  
  <pre><code>// compress xml using zlib
  var xml:XML = &lt;contents&gt;&lt;thing&gt;value&lt;/thing&gt;&lt;/contents&gt;;
  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);
  </code></pre>
  
  <p>Receiving it in the Java servlet and creating the file:</p>
  
  <pre><code>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();
  }
  </code></pre>
  
  <p>Opening the new file in AS3:</p>
  
  <pre><code>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);
  }
  </code></pre>