More of AIR Gzip compression

Further to Marko's blog entry on implementing Gzip compression in AIR applications - turns out we were impressively hoodwinked.

By adding the 'Accept-Encoding':'gzip' header we were telling our apache server to serve up the compressed version of the content and we could see the content was compressed coming through Charles Proxy, and our application was working perfectly.

However, I started working on the exact same code the next day and straight away got an error - the application was erroring because it was getting binary data where it expected the decompressed XML data.

I turned Charles back on to see what was going on and it started working again. With my best sherlock holmes head on I rapidly deduced that Charles as well as proxying the request was also decompressing it helpfully for me.

Luckily I'd already come across the solution to the problem courtesy of Anirudh Sasikumar (GzipHTTPService) and Paul Robertson (Gzip Encoder).

I made some minor modifications to Anirudh's Gzip HTTP Service to do two things.

  • Always send the header 'Accept-Encoding':'gzip' if running a Desktop (Aka AIR) app.
  • Handle the case where the Gzip response that comes back is not gzip compressed. I.e. Charles already decrypted it or the server doesn't support gzip compression.
  • Change it to use version 0.2.0 of the gzip encoder

With these changes it is a drop in replacement for the <mx:HTTPService/> tag.

The changes are as follows:

...snip....
public function GzipHTTPService(rootURL:String=null, destination:String=null)
{
super(rootURL, destination);
         //If using AIR then set accept GZIP          if(Capabilities.playerType == "Desktop")
         {
            this.headers = {'Accept-Encoding':'gzip'};
         }
}

...snip....
else if ( body is ByteArray )
{
var barr:ByteArray = body as ByteArray;

try{
   var encoder:GZIPBytesEncoder = new GZIPBytesEncoder();
   /* decode the gzip encoded result */
   message.body = encoder.uncompressToByteArray(barr).toString();
}catch(error:IllegalOperationError){
   //Not gzip compressed - assume utf8    barr.position = 0;//reset to start of bytearray    message.body = barr.readUTFBytes(barr.length);
}
/* pass it on to HTTPService */
return super.processResult(message, token);            
}

...snip...

For convenience you can download the modified files from here.

Hope it helps.

Cheers, Mark

Comments
Comments are not allowed for this entry.
BlogCFC was created by Raymond Camden. This blog is running version 5.1.004.