I've been thinking about stream converters, content-encoding, and the
interaction of necko with consumers for a bit now...  and I'm somewhat at a
loss for ideas, so I thought I'd float what I have so far and see what people
think.  So:

Goal: The necko consumer should havecontrol over the transformations applied to
      the data, especially decompression.  This means that the necko consumer
      should be able to affect, to some extent, what stream converters, are
      inserted into the data stream.

Given:  The necko consumer implements nsIStreamListener and needs to
        communicate its wishes in its OnStartRequest method.  This interface is
        frozen, so not much we can do here.

Problem:  Some stream converters cache data and delay firing OnStartRequest (eg
          nsUnknownDecoder).

Use Case: We should be able to detect file:///tmp/foo as
          application/postscript with a gzip encoding when the data is gzipped
          postscript.

Proposed approach:

What we could do in this case is to instantiate an nsUnknownDecoder to detect
thr type (either in the URILoader or directly in the file: channel).  The
unknown decoder could be taught about gzip, and when it detects a gzipped
stream it could gunzip its internal buffer, resniff the content type of the
result, and set the type on the channel to the gunzipped type (and the content
encoding to "gzip").   Then it could fire OnStartRequest and based on what the
consumer decided during the OnStartRequest it could insert a gunzipping
converter or not.  The issue is that there could be a converter further down
the line that traps the OnStartRequest just like nsUnknownDecoder itself does.
A second problem is that the consumer has no access to the decoder, but only to
the nsIRequest.

I'm very much at a loss to deal with the problem of multiple decoders that
delay OnStartRequest.  For the other problem, we could have the final consumer
call a function on the channel saying whether it wants decoding and passing a
pointer to its streamlistener interface.  The channel would QI its listener to
nsIStreamConverter and if the QI succeeds call a similar function on that,
passing in the pointer it got.  The notification would propagate down the line
of stream converters that way...  The converter whose listener matches the
pointer being passed along (this could be the channel itself) would not
propagate the notification any further.  It's a little clunky, but it works, I
think...

Thoughts?  Suggestions?
        
Boris
-- 
Modern art is what happens when painters stop looking at girls and 
persuade themselves that they have a better idea.
                                          -- John Ciardi

Reply via email to