Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't POST JSON to server using Netty

I'm stuck on a really, really basic problem: Using HttpRequest to POST a wee bit of JSON to a server using Netty.

Once the channel is connected, I prepare the request like this:

HttpRequest request = new DefaultHttpRequest(
    HttpVersion.HTTP_1_1, HttpMethod.POST, postPath);
request.setHeader(HttpHeaders.Names.CONTENT_TYPE, "application/json");
String json = "{\"foo\":\"bar\"}";
ChannelBuffer buffer = ChannelBuffers.copiedBuffer(json, CharsetUtil.UTF_8);
request.setContent(buffer);

channel.write(request);
System.out.println("sending on channel: " + json);

The last line prints out {"foo":"bar"}, which is well-formed JSON.

However, a really simple echo server I wrote in Python using Flask shows the request, but it has no body or json field, like the body couldn't be parsed into JSON correctly.

When I simply use curl to send the same data, then the echo server does find and parse the JSON correctly:

curl --header "Content-Type: application/json" -d '{"foo":"bar"}' -X POST http://localhost:5000/post_path

My pipeline in Netty is formed with:

return Channels.pipeline(
    new HttpClientCodec(),
    new MyUpstreamHandler(...));

Where MyUpstreamHandler extends SimpleChannelUpstreamHandler and is what attempts to send the HttpRequest after the channel connects.

Again, I'm at a total loss. Any help would be greatly appreciated.

like image 563
shadowmatter Avatar asked Dec 28 '22 03:12

shadowmatter


2 Answers

As Veebs said, you have to set some http headers, I too had same the problem and lost for hours, I got it working with following code :).

    import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;

    ......  

    HttpRequest httpRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/post_path");

    final ChannelBuffer content = ChannelBuffers.copiedBuffer(jsonMessage, CharsetUtil.UTF_8);

    httpRequest.setHeader(CONTENT_TYPE, "application/json");
    httpRequest.setHeader(ACCEPT, "application/json");

    httpRequest.setHeader(USER_AGENT, "Netty 3.2.3.Final");
    httpRequest.setHeader(HOST, "localhost:5000");

    httpRequest.setHeader(CONNECTION, "keep-alive");
    httpRequest.setHeader(CONTENT_LENGTH, String.valueOf(content.readableBytes()));

    httpRequest.setContent(content);

    channel.write(httpRequest);
like image 118
Jestan Nirojan Avatar answered Dec 29 '22 16:12

Jestan Nirojan


Not sure if you have http keep alive on or not, but if you do, you may have to send the content length in the header.

like image 25
Veebs Avatar answered Dec 29 '22 16:12

Veebs