Search code examples
javaandroidnionettyandroid-assets

Serving a file with Netty - response is truncated by one byte


I've serving a files from Android assets via Netty server (images, html). Text files such a html is saved as .mp3 to disable compression (I need an InputStream!)

My pipeline is looking like this:

    pipeline.addLast("decoder", new HttpRequestDecoder());
    pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
    pipeline.addLast("encoder", new HttpResponseEncoder());
    pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());

    pipeline.addLast("handler", new AssetsServerHandler(context));

My handler is:

public class AssetsServerHandler extends SimpleChannelUpstreamHandler {

    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {

        // some checks

        final FileInputStream is;
        final AssetFileDescriptor afd;
        try {
            afd = assetManager.openFd(path);
            is = afd.createInputStream();   
        } catch(IOException exc) {
            sendError(ctx, NOT_FOUND);
            return;
        }

        final long fileLength = afd.getLength();

        HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
        setContentLength(response, fileLength);

        final Channel ch = e.getChannel();
        final ChannelFuture future;
        ch.write(response);
        future = ch.write(new ChunkedStream(is));
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                future.getChannel().close();
            }
        });
        if (!isKeepAlive(request)) {
            future.addListener(ChannelFutureListener.CLOSE);
        }
    }
    // other stuff
}

With that handler i've got my resposes truncated by at least one byte. If I change ChunkedStream to ChunkedNioFile (and so use a is.getChannel() instead of is as a constructor to it) - everything works perfectly.

Please, help me understand what is wrong with ChunkedStream.


Solution

  • Your code looks right to me. Does the returned FileInputStream of AssetFileDescriptor contain "all the bytes" ? You could check this with a unit test. If there is no bug in it then its a bug in netty. I make heavy use of ChunkInputStream and never had such a problem yet, but maybe it really depends on the nature of the InputStream.

    Would be nice if you could write a test case and open a issue at netty's github.