http.HTTPClient.java Source code

Java tutorial

Introduction

Here is the source code for http.HTTPClient.java

Source

/*
*  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package http;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpScheme;
import io.netty.handler.codec.http2.Http2SecurityUtil;
import io.netty.handler.codec.http2.HttpConversionUtil;
import io.netty.handler.ssl.ApplicationProtocolConfig;
import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol;
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior;
import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior;
import io.netty.handler.ssl.ApplicationProtocolNames;
import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.util.AsciiString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * An HTTP2 client that allows you to send HTTP2 frames to a server. Inbound and outbound frames are
 * logged. When run from the command-line, sends a single HEADERS frame to the server and gets back
 * a "Hello World" response.
 */
public class HTTPClient {

    private static final Logger log = LoggerFactory.getLogger(HTTPClient.class);

    private AtomicInteger streamId = new AtomicInteger(1);
    private Channel channel;
    private EventLoopGroup workerGroup;
    private HTTPResponseHandler responseHandler;
    private HttpScheme scheme;
    private AsciiString hostName;

    public HTTPClient(boolean ssl, String host, int port) throws Exception {

        try {

            final SslContext sslCtx;
            if (ssl) {
                SslProvider provider = OpenSsl.isAlpnSupported() ? SslProvider.OPENSSL : SslProvider.JDK;
                sslCtx = SslContextBuilder.forClient().sslProvider(provider)
                        .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE)
                        .trustManager(InsecureTrustManagerFactory.INSTANCE)
                        .applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN,
                                // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers.
                                SelectorFailureBehavior.NO_ADVERTISE,
                                // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers.
                                SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2,
                                ApplicationProtocolNames.HTTP_1_1))
                        .build();
            } else {
                sslCtx = null;
            }
            workerGroup = new NioEventLoopGroup();
            HTTPClientInitializer initializer = new HTTPClientInitializer(sslCtx, Integer.MAX_VALUE);

            // Configure the client.
            Bootstrap b = new Bootstrap();
            b.group(workerGroup);
            b.channel(NioSocketChannel.class);
            b.option(ChannelOption.SO_KEEPALIVE, true);
            b.remoteAddress(host, port);
            b.handler(initializer);

            // Start the client.
            channel = b.connect().syncUninterruptibly().channel();
            log.info("Connected to [" + host + ':' + port + ']');

            // Wait for the HTTP/2 upgrade to occur.
            //            HTTPSettingsHandler http2SettingsHandler = initializer.settingsHandler();
            //            http2SettingsHandler.awaitSettings(TestUtil.HTTP2_RESPONSE_TIME_OUT, TestUtil.HTTP2_RESPONSE_TIME_UNIT);
            //            responseHandler = initializer.responseHandler();
            scheme = ssl ? HttpScheme.HTTPS : HttpScheme.HTTP;
            hostName = new AsciiString(host + ':' + port);

        } catch (Exception ex) {
            log.error("Error while initializing http2 client " + ex);
            this.close();
        }

    }

    public int send(FullHttpRequest request) throws Exception {

        // Configure ssl.
        int currentStreamId = streamId.addAndGet(2);
        request.headers().add(HttpHeaderNames.HOST, hostName);
        request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), scheme.name());
        responseHandler.put(currentStreamId, channel.write(request), channel.newPromise());
        channel.flush();
        log.info("Finished HTTP request");
        return currentStreamId;
    }

    public void close() {

        // Wait until the connection is closed.
        if (channel != null && channel.isActive()) {
            channel.close().syncUninterruptibly();
        }
        if (workerGroup != null) {
            workerGroup.shutdownGracefully();
        }
    }

    public String getResponse(int streamId) {
        return responseHandler.getResponse(streamId);

    }
}