Hi Oleg,

here are my thoughts on this, still preliminary.

I think we need a way to layer output streams (when sending) and
input streams (when receiving). That's for chunked encoding, for
transport compression and decompression, content compression and
decompression (not supported by us, but added by applications),
for progress monitoring, for statistical analysis, for dumping
copies of the data that is sent or received, or other things
developers will come up with.

The standard approach to directly take an output stream and wrap
others around it has some limitations. For example, http-async
performs request preprocessing before allocating a connection,
so there is no stream yet. Of course that can be solved by using
a dummy stream that can be directed to another stream later.
A second drawback is that the order in which the streams are
created is fixed. There is no way to insert a debug or progress
monitoring stream inbetween.
These limitations can be overcome (on the sending side) if the
request preprocessing does not create actual streams, but only
defines a list of streams to be layered later on. Elements can
be inserted into the list at any position. The actual creation
of the streams is deferred to the connection. As a first idea,
the elements in the list could be:
- Class objects for stream classes that have a constructor which
  accepts a stream as the only argument. The classes will be
  instantiated via reflections.
- Instances of a factory interface, for streams that need more
  parameters than just the underlying stream:

    interface OutputStreamFactory {
        public OutputStream create(OutputStream) throws ...;
    }

This would move the logic for choosing the various streams into
the preprocessing classes, while actual streams are still created
in the connection. The connection would not have to expose the
output stream, though the arbitrarily layered streams can of course
screw up the entity that is sent. The current code for choosing a
chunked or plain stream can remain in place as a default, so the
connections can still be used directly. Or else that code is moved
to an OutputStreamFactory, which becomes the default.

On the receiving side, a symmetric approach can be used. Instead
of returning a BasicHttpEntity with fully initialized streams,
the connection returns a ProtoHttpEntity:

    interface ProtoHttpEntity extends BasicHttpEntity {
        public void setStreamStack(List) throws ...;
    }

The ProtoHttpEntity object does not return an input stream until
the list of streams to be layered is provided. The response
interceptors can build that list, and only at the end will the
entity content be accessible. The socket input stream remains
protected, except from a custom stream implementation that is
inserted at the bottom of the stream stack.


Is that in line with your ideas? Am I over-designing ;-?

During the next few days, I have to prepare a written test for
the students that failed the first one. I won't have the time
to provide a patch of this magnitude this week-end. If you can
wait for two or three weeks, I would try to implement the design
that will come out of this discussion. But if you're in the mood
for hacking, I don't want to stop you :-)

cheers,
  Roland


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to