Hi Gabriel,

You are correct, a SWF request is not going to implement
nsIUploadChannel. The documentation on the nsIUploadChannel interface
states: "A channel may optionally implement this interface if it
supports the notion of uploading a data stream." An AMF request POSTs
binary data in the same manner as an HTML form POSTs a file upload,
thus it "supports the notion of uploading a data stream" and you can
QI those requests to nsIUploadChannel.

Now, why do we even need the uploadStream? If you look at how Firebug
does caching (sourceCache.js and tabCache.js) you will see it uses the
URL for the cache key. Unfortunately AMF requests typically all go to
the same endpoint (URL) so we can't use the URL as the cache key. Thus
for AMF requests we get the POSTed data and use its hash as the cache
key.

Having said all that, I would probably just use the URL for the cache
key for SWF requests.

As for why reading the binary data is so difficult, I wish I knew.
It's possible the C++ interfaces for reading binary data are better,
but then you would have to know C++ ;)

Anyway, I hope that helps. May I ask why you are looking to cache SWFs
in Firebug?

--Nathan (Developer of AMF Explorer)



On Wed, Jun 23, 2010 at 8:14 AM, gmariani <[email protected]> wrote:
>
> Yeah, i worked with him originally and got as far as i did. But this
> solution no longer seems to work which is why i'm posting on here.
>
> - gabriel
>
> On Jun 22, 1:13 pm, Pedro Simonetti Garcia <[email protected]>
> wrote:
> > Do you know about Firebug "AMF Explorer" 
> > extension?https://addons.mozilla.org/en-US/firefox/addon/78928/
> >
> > I don't know how AMF works, but maybe the developer
> > of "AMF Explorer" extension know what you are trying
> > to accomplish.
> >
> > regards,
> >
> > Pedro Simonetti.
> >
> > 2010/6/22 gmariani <[email protected]>:
> >
> > > 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 
> > > athttp://groups.google.com/group/firebug?hl=en.
>
> --
> 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.
>

-- 
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