Search code examples
nettymultipart

Netty: Http multipart content has header details mixed with file content


On retrieving content from a FullHttpRequest, I still see http header data in the content -

$> cat /tmp/ABC

------------------------------c9f68c9ab255
Content-Disposition: form-data; name="file"; filename="file_to_upload"
Content-Type: application/octet-stream

abcd

------------------------------c9f68c9ab255--

I'm submitting the upload using curl -

$> cat /tmp/file_to_upload
abcd
$> curl -F "file=@/tmp/file_to_upload" -X POST http://<host>:<port>/upload

I'm using Netty-4.1.9.Final. I set up these handlers for my NettyServer -

channel.pipeline().addLast(new HttpServerCodec());
channel.pipeline().addLast(new HttpObjectAggregator(1048576));
channel.pipeline().addLast(new MyFullHttpHandler());

In MyFullHttpHandler(), I'm saving the uploaded file like this -

public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
    if (msg instanceof FullHttpRequest) {
        FullHttpRequest request = (FullHttpRequest) msg;
        FileChannel fileChannel = new FileOutputStream("/tmp/ABC").getChannel();

        ByteBuffer buffer = request.content().nioBuffer();
        try {
              while (buffer.hasRemaining()) {
                   fileChannel.write(buffer);
              }
        } catch (Exception e) {
              System.out.println(e);
        } finally {
            fileChannel.close();
        }
    }
}

I tried without the HttpObjectAggregator and used a technique similar to what is here, and the content appears to be correct.

Am I using HttpObjectAggregator incorrectly? Is this a known issue? Appreciate any help.

=== UPDATE ===

I wasn't using a decoder on the content. The following couple of lines fixed the issue I was having -

HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(true), req);
InterfaceHttpData data = decoder.next();

You can use DiskFileUpload to save the uploaded data to a file.


Solution

  • I wasn't using a decoder on the content. The following couple of lines fixed the issue I was having -

    HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(true), req);
    InterfaceHttpData data = decoder.next();