0

I'm trying to use Apache HttpClient (the fluent API) to POST data to a netty server.

I've tried a few variations, I'll put two here:

1.

Client:

Request.Post(uri).bodyString("content value", ContentType.TEXT_PLAIN).useExpectContinue().execute().returnContent().asString();

Server:

final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), req);              
System.out.println(decoder.getBodyHttpDatas().size());

Calling getBodyHttpDatas() throws a:

io.netty.handler.codec.http.multipart.HttpPostRequestDecoder$NotEnoughDataDecoderException

2.

Client:

Request.Post(uri).bodyForm(new BasicNameValuePair("value", "content value")).useExpectContinue().execute().returnContent().asString();

Server:

final HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), req);
final InterfaceHttpData data1 = decoder.getBodyHttpData("value");

while (decoder.hasNext()) {
    final InterfaceHttpData data = decoder.next();
    if (data != null) {
        try {
            Attribute attribute = (Attribute) data;
            System.out.println(attribute.getValue());
        } finally {
            data.release();
        }
    }
}

This doesn't print any output - decoder.hasNext() is false.

rich
  • 18,987
  • 11
  • 75
  • 101
  • 2
    it's difficult to deal with 2 issues at the same time, I would try to separate the two problems : use curl to send POST data to you server, make it work and then make your client work. – Pixou Jun 04 '14 at 15:55
  • Have you tried with these examples http://www.vogella.com/tutorials/ApacheHttpClient/article.html? What happen when you do that? – Federico Piazza Jun 04 '14 at 22:53
  • curl -X POST -d @value.txt [url] gives me the NotEnoughDataDecoderException too. I haven't tried the non-fluent HttpClient API, but I don't believe that's the issue particularly as curl fails similarly. – rich Jun 05 '14 at 07:54
  • Oh, and curl --form "value=@value.txt" [url] also fails with the NotEnoughDataDecoderException. – rich Jun 05 '14 at 07:54
  • Could you trace in your server part what is in you request (`req`) body before trying to decode it ? – Serge Ballesta Jun 05 '14 at 08:29
  • As you can see in the API the exception is thrown due to missing chunks: [API](http://netty.io/3.5/api/org/jboss/netty/handler/codec/http/multipart/HttpPostRequestDecoder.html#getBodyHttpDatas%28%29). - Do you mind calling `offer(...)` first or add a pause of 500ms (for test purposes only)? – Markus Jun 05 '14 at 08:55
  • Can't see anything unexpected in the request. There's no body I can see on the request, there is a decoderResult which has a success value. – rich Jun 05 '14 at 14:13
  • Pausing doesn't seem to help. I haven't been able to figure out how to get an HttpContent to pass to offer(). – rich Jun 05 '14 at 14:15

1 Answers1

5

To solve the problem you either need to offer() all chunks (HttpContent) of a message to HttpPostRequestDecoder before calling getBodyHttpDatas(), or alternatively you can just add the HttpObjectAggregator handler right before your handler to the channel's pipeline. If you do so, HttpObjectAggregator will collect all chunks for you and produce a single FullHttpRequest in place of multiple chunks. Passing FullHttpRequest instead of an ordinary HttpRequest to HttpPostRequestDecoder's constructor eliminates need to offer() chunks.

So you just need to pipeline.addLast(new HttpObjectAggregator(1048576)) before adding your handler. For example:

public class YourServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new HttpObjectAggregator(1048576));
        pipeline.addLast(new YourServerHandler());
    }
}

1048576 here is the maximum length of the aggregated content. You are free to pass another value.

dened
  • 4,253
  • 18
  • 34
  • Thanks, there were other issues with my handler, but I managed to modify the code at http://stackoverflow.com/questions/23651447/netty-io-client-not-sending-request-body to my needs. This then solved the next problem. – rich Jun 07 '14 at 07:37