Announcing LittleProxy 0.1 based on Netty
Stephen Haberman
stephen at exigencecorp.com
Sun Nov 1 06:37:40 EST 2009
> I'd like to announce the release of LittleProxy 0.1, based on Netty.
Spiffy.
I've recently written a netty-based proxy as well and have been meaning
to post it somewhere. I was interested to see how you went about
tackling the same problem, so read through some of the code.
> http://dev.littleshoot.org:8081/browse/LP-1
I tried your test image in my own netty proxy, with an interesting
result.
Initially, it loaded fine. However, I'm not using HttpResponseDecoder in
the relaying pipeline, and instead just putting onto the browser channel
whatever raw bytes show up on the relay channel.
I had a HttpResponseDecoder in the relay pipeline originally, but took
it out because I'm not introspecting/modifying the returning data.
So, if I put HttpResponseDecoder back in my relay pipeline, your test
image no longer loads and I get this exception:
2 - Incoming exception java.io.IOException: Connection reset by peer
java.io.IOException: Connection reset by peer
at sun.nio.ch.FileDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:251)
at sun.nio.ch.IOUtil.read(IOUtil.java:224)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:254)
at org.jboss.netty.buffer.HeapChannelBuffer.setBytes(HeapChannelBuffer.java:156)
at org.jboss.netty.buffer.AbstractChannelBuffer.writeBytes(AbstractChannelBuffer.java:425)
at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:305)
at org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:275)
at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:196)
at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)
Okay, here's what I'm seeing so far:
1) Without HttpResponseDecoder it works all the time
2) With HttpResponseDecoder it never works, /but/ I only get the above
stack trace /most/ of the time. Several times I'll see no errors in
my console, but firefox still doesn't load the image.
This seems to be the behavior you're seeing--I have no idea why
sometimes I see a stack trace and sometimes not.
3) With HttpResonseDecoder+HttpChunkAggregator it does work. Isn't
that odd...
4) When I do see the exception, it's not on the outgoing/relay channel,
it's on the incoming/browser channel. E.g. the message object is read
in perfectly fine from the relay channel, it's only when I drop that
message into the browser channel that the exception occurs.
So, it looks like there is a bug in HttpResponseDecoder where its not
making a copy of some data, e.g. it reads it lazily from the source
relay channel. This image/host seems to be large/quick enough to be
disconnecting before the data can get out to the browser. However, this
only sometimes causes exceptions to be reported (even though the image
never loads in the browser), and can also be avoided by using
HttpChunkAggregator which probably copies the data off the wire in a way
that HttpResponseDecoder does not.
So it looks like the raw byte messages can be shared cross channels,
the aggregated response messages can be shared cross channels, but
the non-aggregated response messages cannot be shared cross channels--
not sure whether this is a known property that we're violating or a
bug.
- Stephen
More information about the netty-users
mailing list