GZIP-Encoded HTTP Response in Adobe AIR

A common way to reduce the size of data returned over HTTP is to allow the web server to use a GZIP compression on the data. When making requests in a Flash/Flex application hosted in a web browser, the browser actually uncompresses the GZIP-encoded data before its delivered to Flash Player. Therefore, Flash/Flex developers don’t need to worry about GZIP-encoded data since its handled seemlessly behind the scenes. However, when writing an application in AIR, there is no browser to handle the GZIP compression and AIR 1.0 doesn’t have this built-in. (I assume they will add this in a dot release at some point.)

But there is a way to do it manually. The ByteArray in AS3 supports DEFLATE compression. However, you must first remove the header in the GZIP data for this to work properly. In my case, I was making a web service call using the WebService class in Flex. Since I actually needed to get at the raw binary GZIP data returned by the server, I had to change my code to use the low-level URLLoader class that is built-in to Flash Player.

To remove the GZIP header returned in the HTTP response data, I used an open-source library created by Paul Robertson. The library works with GZIP files in AIR, but I was able to slightly modifie it to work directly with the ByteArray data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import com.probertson.utils.GZIPEncoder;
import com.probertson.utils.GZIPFile;
 
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import flash.utils.ByteArray;
import flash.utils.CompressionAlgorithm;
 
var request:URLRequest = new URLRequest();
request.url = "YOUR_SERVICE_ENDPOINT";
request.method = URLRequestMethod.POST;
request.contentType = "text/xml; charset=utf-8";
request.requestHeaders.push(new URLRequestHeader("SOAPAction", "YOUR_SOAP_ACTION"));
request.requestHeaders.push(new URLRequestHeader("Accept-Encoding", "gzip"));
request.data = <soap-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-ENV:Body>
        <your_SOAP_BODY />
    </soap-ENV:Body>
</soap-ENV:Envelope>;
 
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onResult, false, 0, true);
loader.load(request);
 
private function onResult(event:Event) {
    try {
        var rawData:ByteArray = URLLoader(event.target).data as ByteArray;
        var encoder:GZIPEncoder = new GZIPEncoder();
        var gzipData:GZIPFile = encoder.parseGZIPData(rawData);
        var uncompressedData:ByteArray = gzipData.getCompressedData();
        uncompressedData.uncompress(CompressionAlgorithm.DEFLATE);
        var soapData:XML = new XML(uncompressedData.toString());
        trace(soapData);
    }catch(error:Error) {
        trace(error.message);
    }
}

Update: Paul has recently included my proposed change in his library. Therefore, you can now check out the code from his Google Code SVN repository here.

5 thoughts on “GZIP-Encoded HTTP Response in Adobe AIR

  1. Paul Robertson

    I thought it might make sense to let you know that I’ve made a change to the gzip library to make this type of operation easier. (I finally needed it myself, so naturally I improved it =).

    The code listing above will still work just fine, but now (as of version 1.0.1 of the library) you can also do the following instead of the lines in the try{} block:

    var rawData:ByteArray = URLLoader(event.target).data as ByteArray;
    var encoder:GZIPEncoder = new GZIPEncoder();
    var uncomprssedData:ByteArray = encoder.uncompressToByteArray(rawData);
    var soapData:XML = new XML(uncompressedData.toString());
    trace(soapData);

    Basically, I refactored the uncompressToByteArray() method so that it now accepts a compressed ByteArray as an argument. Before it only accepted a File argument (and it still accepts a File in addition to a ByteArray).

    Reply
  2. Andrew

    Thanks for this valuable information.

    HTTP GZIP compression should really be built into AIR though – it’s akin to failing to build in HTTP/1.1

    Andrew

    Reply
  3. akhil

    i have a commpressed bytestream of an image using gzip i want to uncompress this in flex webapplication not in AIR is there a way to do this

    Reply