All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.webpieces.httpclient.impl.HttpClientSocketImpl Maven / Gradle / Ivy

package org.webpieces.httpclient.impl;

import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.CompletableFuture;

import javax.net.ssl.SSLEngine;

import org.webpieces.httpclient.api.HttpClientSocket;
import org.webpieces.httpclient.api.HttpsSslEngineFactory;
import org.webpieces.httpcommon.api.CloseListener;
import org.webpieces.httpcommon.api.RequestSender;
import org.webpieces.httpparser.api.HttpParser;
import org.webpieces.nio.api.ChannelManager;
import org.webpieces.nio.api.channels.Channel;
import org.webpieces.nio.api.channels.TCPChannel;
import org.webpieces.nio.api.handlers.DataListener;
import org.webpieces.nio.api.handlers.RecordingDataListener;
import org.webpieces.util.logging.Logger;
import org.webpieces.util.logging.LoggerFactory;

import com.webpieces.http2parser.api.Http2Parser;
import com.webpieces.http2parser.api.Http2SettingsMap;


public class HttpClientSocketImpl implements HttpClientSocket, Closeable {

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

    private TCPChannel channel;
    private HttpParser httpParser;
    private Http2Parser http2Parser;
    private Http2SettingsMap http2SettingsMap;

    private CompletableFuture connectFuture;
    private boolean isClosed;
    private CloseListener closeListener;
    private HttpsSslEngineFactory factory;
    private ChannelManager mgr;
    private String idForLogging;
    private boolean isRecording = false;

    private RequestSenderImpl requestSender;

    public HttpClientSocketImpl(
        ChannelManager mgr,
        String idForLogging,
        HttpsSslEngineFactory factory,
        HttpParser httpParser,
        Http2Parser http2Parser,
        CloseListener closeListener,
        Http2SettingsMap http2SettingsMap)
    {
        this.factory = factory;
        this.mgr = mgr;
        this.idForLogging = idForLogging;
        this.closeListener = closeListener;
        this.http2Parser = http2Parser;
        this.httpParser = httpParser;
        this.http2SettingsMap = http2SettingsMap;
    }

    @Override
    public TCPChannel getUnderlyingChannel() {
        return channel;
    }

    // HTTP Socket interface calls
    @Override
    public CompletableFuture connect(InetSocketAddress addr) {
        if (factory == null) {
            channel = mgr.createTCPChannel(idForLogging);
        } else {
            SSLEngine engine = factory.createSslEngine(addr.getHostName(), addr.getPort());
            channel = mgr.createTCPChannel(idForLogging, engine);
        }

        requestSender = new RequestSenderImpl(
            this,
            this.httpParser,
            this.http2Parser,
            closeListener,
            addr,
            channel,
            http2SettingsMap
            );
        DataListener dataListener;

        if (isRecording) {
            dataListener = new RecordingDataListener("httpSock-", requestSender.getDataListener());
        } else {
            dataListener = requestSender.getDataListener();
        }

        connectFuture = channel.connect(addr, dataListener).thenApply(channel -> requestSender);
        return connectFuture;
    }

    @Override
    public CompletableFuture closeSocket() {
        if (isClosed) {
            return CompletableFuture.completedFuture(null);
        }
        requestSender.cleanUpPendings("close socket called");

        CompletableFuture future = channel.close();
        return future.thenAccept(chan -> {
            isClosed = true;
        });
    }

    @Override
    public RequestSender getRequestSender() {
        return requestSender;
    }

    @Override
    public void close() throws IOException {
        if(isClosed)
            return;

        //best effort and ignore exception except log it
        CompletableFuture future = closeSocket();
        future.exceptionally(e -> {
            log.info("close failed", e);
            return null;
        });
    }

	@Override
	public String toString() {
		return "HttpClientSocket["+idForLogging+", channel="+channel+"]";
	}
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy