Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unable to read response in http client using netty

I am able to write my http request over the connection made to the server but I am unable to read the response from the server(not sure if there is any response or not).. How can I check it and then read it? My server is returning json in response..

Client code :

public class NettyClient {



      public static void main(String[] args) throws Exception {
           URI uri = new URI("http://myurl.com/v1/v2?param1=value1");          
           String scheme = uri.getScheme() == null? "http" : uri.getScheme();
           String host = uri.getHost();
            int port = 443;

            boolean ssl = "https".equalsIgnoreCase(scheme);

         // Configure the client.
            EventLoopGroup group = new NioEventLoopGroup();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group)
                 .channel(NioSocketChannel.class)
                 .handler(new NettyClientInitializer(false));
                // Make the connection attempt.
                Channel ch = b.connect(host, port).sync().channel();
                // Prepare the HTTP request.
                HttpRequest request = new DefaultHttpRequest(
                        HttpVersion.HTTP_1_1, HttpMethod.GET, "http://myurl.com/v1/v2?param1=value1");
                request.headers().set(HttpHeaders.Names.HOST, host);
                request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);            
                //request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);

                // Send the HTTP request.
                ch.writeAndFlush(request);

                // Wait for the server to close the connection.
                ch.closeFuture().sync();
            } finally {
                // Shut down executor threads to exit.
                group.shutdownGracefully();
            }
      }
}

Initializer code :

public class NettyClientInitializer extends ChannelInitializer<SocketChannel> {

    private final boolean ssl;

    public NettyClientInitializer(boolean ssl) {
        this.ssl = ssl;
    }

    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        // Create a default pipeline implementation.
        ChannelPipeline p = ch.pipeline();

        p.addLast("log", new LoggingHandler(LogLevel.INFO));
        // Enable HTTPS if necessary.
        /*
        if (ssl) {
            SSLEngine engine =
                SecureChatSslContextFactory.getClientContext().createSSLEngine();
            engine.setUseClientMode(true);

            p.addLast("ssl", new SslHandler(engine));
        }
*/
        p.addLast("codec", new HttpClientCodec());

        // Remove the following line if you don't want automatic content decompression.
       // p.addLast("inflater", new HttpContentDecompressor());

        // Uncomment the following line if you don't want to handle HttpChunks.
        //p.addLast("aggregator", new HttpObjectAggregator(1048576));
        p.addLast("handler", new NettyClientHandler());
    }
}

Handler code :

public class NettyClientHandler extends SimpleChannelInboundHandler<HttpObject> {

    @Override
    public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
        if (msg instanceof HttpResponse) {
            HttpResponse response = (HttpResponse) msg;

            System.out.println("STATUS: " + response.getStatus());
            System.out.println("VERSION: " + response.getProtocolVersion());
            System.out.println();

            if (!response.headers().isEmpty()) {
                for (String name: response.headers().names()) {
                    for (String value: response.headers().getAll(name)) {
                        System.out.println("HEADER: " + name + " = " + value);
                    }
                }
                System.out.println();
            }

            if (HttpHeaders.isTransferEncodingChunked(response)) {
                System.out.println("CHUNKED CONTENT {");
            } else {
                System.out.println("CONTENT {");
            }
        }
        if (msg instanceof HttpContent) {
            HttpContent content = (HttpContent) msg;

            System.out.print(content.content().toString(CharsetUtil.UTF_8));
            System.out.flush();

            if (content instanceof LastHttpContent) {
                System.out.println("} END OF CONTENT");
            }
        }
    }

    @Override
    public void exceptionCaught(
            ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }


}

In the console I can see the request being written but after that the request is flushed, the channel is then inactive and then unregistered.

Could the reason be that my query parameters are not being sent or json issue or am I missing something in my code?

like image 488
Mitaksh Gupta Avatar asked Nov 11 '22 18:11

Mitaksh Gupta


1 Answers

The problem likely lies in the fact you're connecting to your server on port 443

int port = 443;
...
Channel ch = b.connect(host, port).sync().channel();

But your NettyClientInitializer doesn't support SSL (it's commented out of the pipeline) and you construct it as if SSL is not being used anyway

new NettyClientInitializer(false)

Your code works fine if you change the port to 80.

like image 157
Derek Troy-West Avatar answered Nov 15 '22 11:11

Derek Troy-West