How do you grab the actual binary data for an item loaded? I want to
parse through a SWF that is loaded from a given site.

Previously I had trouble grabbing the binary data of a network
response (AMF) and got that working. Although I'm still not sure *how*
it works, just that it does, more on that later. I tried to use the
same method there to grab the SWF data with no success.

I have a (TabCacheModel) CacheListener setup to tell Firebug to cache
both AMF and SWF requests. It creates a cache key, stores it for
later. Then for the (NetMonitor) NetListener.onResponseBody, it gets a
response stream from the cache using that cache key. Once I have the
response stream, when a user goes to view the tab added to the Net
panel it creates a nsISeekableStream. With that I parse and display
the AMF data.

When I try to do this to grab the SWF data this is what happens. At
CacheListener.onDataAvailable, it goes to retrieve the cache key based
on the request.

function getCacheKey(request) {
        var uploadStream =
request.QueryInterface(Ci.nsIUploadChannel).uploadStream;

        var seekableStream =
uploadStream.QueryInterface(Ci.nsISeekableStream);
        seekableStream.seek(NS_SEEK_SET, 0);

        var ch = Cc["@mozilla.org/security/hash;
1"].createInstance(Ci.nsICryptoHash);
        ch.init(ch.MD5);
        ch.updateFromStream(seekableStream, seekableStream.available());

        return ch.finish(true);
};

But for the SWFs, uploadStream is null and it explodes. Does it matter
that the SWF is a file and not part of the request? Is that why this
approach is failing? How can I fix this so it doesn't hate life.

*gripe start*
Getting back to how I think this whole setup is a bit of black magic.
The method just to retrieve the binary data of a response seems really
complicated. You have to register a TabCacheModel and NetMonitor
listener. The cache listener tells Firebug to cache certain things.
Then when you get the actual data you have to jump through a ton of
hoops to save that data.

onDataAvailable: function(context, request, requestContext,
inputStream, offset, count)     {
        if (isAmfRequest(request) || isSwfRequest(request)) {
                //try {
                        var cacheKey = getCacheKey(request);

                        if (!cacheKey) return;

                        if (!this.cache[cacheKey]) {
                                this.cache[cacheKey] = {
                                        storageStream: 
Cc["@mozilla.org/storagestream;
1"].createInstance(Ci.nsIStorageStream),
                                        outputStream: 
Cc["@mozilla.org/binaryoutputstream;
1"].createInstance(Ci.nsIBinaryOutputStream)
                                };

                                this.cache[cacheKey].storageStream.init(8192, 
PR_UINT32_MAX,
null);
        
this.cache[cacheKey].outputStream.setOutputStream(this.cache[cacheKey].storageStream.getOutputStream(0));
                        }

                        var binaryInputStream = 
Cc["@mozilla.org/binaryinputstream;
1"].createInstance(Ci.nsIBinaryInputStream);
                        binaryInputStream.setInputStream(inputStream.value);

                        var listenerStorageStream = 
Cc["@mozilla.org/storagestream;
1"].createInstance(Ci.nsIStorageStream);
                        listenerStorageStream.init(8192, count, null);

                        var listenerOutputStream = 
Cc["@mozilla.org/binaryoutputstream;
1"].createInstance(Ci.nsIBinaryOutputStream);
        
listenerOutputStream.setOutputStream(listenerStorageStream.getOutputStream(0));

                        var data = binaryInputStream.readByteArray(count);
                        listenerOutputStream.writeByteArray(data, count);
                        this.cache[cacheKey].outputStream.writeByteArray(data, 
count);

                        var response = this.getResponse(request, cacheKey);
                        response.size += count;

                        // Let other listeners use the stream.
                        inputStream.value = 
listenerStorageStream.newInputStream(0);
                /*} catch (e) {
                        ERROR(e);
                }*/
        }
},

Then the net listener goes into action at onResponseBody to save this
stream you created and assign it to the file that has the request
object.

THEN when you're finally ready to display your information, you have
to do a little bit more magic to turn that stream into something you
can actually read.

var is = file.responseStream;
if (is) {
        var ss = is.QueryInterface(Ci.nsISeekableStream);
        if (ss)  {
                ss.seek(NS_SEEK_SET, 0);

                // Finally have a readable stream!
        }
}

Am I doing something wrong here or is that actually the only way to
get binary data?
*end gripe*

- gabriel

-- 
You received this message because you are subscribed to the Google Groups 
"Firebug" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/firebug?hl=en.

Reply via email to