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

com.king.platform.net.http.netty.requestbuilder.BuiltNettyClientRequest Maven / Gradle / Ivy

There is a newer version: 3.0.26
Show newest version
// Copyright (C) king.com Ltd 2015
// https://github.com/king/king-http-client
// Author: Magnus Gustafsson
// License: Apache 2.0, https://raw.github.com/king/king-http-client/LICENSE-APACHE

package com.king.platform.net.http.netty.requestbuilder;


import com.king.platform.net.http.*;
import com.king.platform.net.http.HttpResponse;
import com.king.platform.net.http.netty.CustomCallbackSubscriber;
import com.king.platform.net.http.netty.HttpClientCaller;
import com.king.platform.net.http.netty.ResponseFuture;
import com.king.platform.net.http.netty.ServerInfo;
import com.king.platform.net.http.netty.eventbus.ExternalEventTrigger;
import com.king.platform.net.http.netty.request.HttpBody;
import com.king.platform.net.http.netty.request.NettyHttpClientRequest;
import com.king.platform.net.http.util.Param;
import com.king.platform.net.http.util.UriUtil;
import io.netty.handler.codec.http.*;

import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.Supplier;

public class BuiltNettyClientRequest implements BuiltClientRequest, BuiltClientRequestWithBody {

	private final HttpClientCaller httpClientCaller;
	private final HttpVersion httpVersion;
	private final HttpMethod httpMethod;
	private final String uri;

	private final String defaultUserAgent;


	private final int idleTimeoutMillis;
	private final int totalRequestTimeoutMillis;

	private final boolean followRedirects;
	private final boolean acceptCompressedResponse;
	private final boolean keepAlive;

	private final RequestBodyBuilder requestBodyBuilder;
	private final String contentType;
	private final Charset bodyCharset;

	private final List queryParameters;
	private final List headerParameters;
	private final Executor callbackExecutor;
	private final Supplier> responseBodyConsumer;

	private HttpCallback httpCallback;
	private NioCallback nioCallback;
	private UploadCallback uploadCallback;

	private Supplier externalEventTriggerSupplier;

	private Supplier> httpCallbackSupplier;
	private Supplier nioCallbackSupplier;
	private Supplier uploadCallbackSupplier;

	private CustomCallbackSubscriber customCallbackSubscriber;


	public BuiltNettyClientRequest(HttpClientCaller httpClientCaller, HttpVersion httpVersion, HttpMethod httpMethod, String uri, String defaultUserAgent, int idleTimeoutMillis, int totalRequestTimeoutMillis, boolean followRedirects, boolean acceptCompressedResponse, boolean keepAlive, RequestBodyBuilder requestBodyBuilder, String contentType, Charset bodyCharset, List queryParameters, List headerParameters, Executor callbackExecutor, Supplier> responseBodyConsumer) {
		this.httpClientCaller = httpClientCaller;
		this.httpVersion = httpVersion;
		this.httpMethod = httpMethod;
		this.uri = uri;
		this.defaultUserAgent = defaultUserAgent;
		this.idleTimeoutMillis = idleTimeoutMillis;
		this.totalRequestTimeoutMillis = totalRequestTimeoutMillis;
		this.followRedirects = followRedirects;
		this.acceptCompressedResponse = acceptCompressedResponse;
		this.keepAlive = keepAlive;
		this.requestBodyBuilder = requestBodyBuilder;
		this.contentType = contentType;
		this.bodyCharset = bodyCharset;
		this.queryParameters = new ArrayList<>(queryParameters);
		this.headerParameters = new ArrayList<>(headerParameters);
		this.callbackExecutor = callbackExecutor;
		this.responseBodyConsumer = responseBodyConsumer;
	}


	@Override
	public BuiltClientRequest withHttpCallback(HttpCallback httpCallback) {
		if (httpCallbackSupplier != null) {
			throw new IllegalStateException("An Supplier has already been provided");
		}
		this.httpCallback = httpCallback;
		return this;
	}

	@Override
	public BuiltClientRequest withHttpCallback(Supplier> httpCallbackSupplier) {
		if (httpCallback != null) {
			throw new IllegalStateException("An HttpCallback has already been provided");
		}
		this.httpCallbackSupplier = httpCallbackSupplier;
		return this;
	}

	@Override
	public BuiltClientRequest withNioCallback(NioCallback nioCallback) {
		if (nioCallbackSupplier != null) {
			throw new IllegalStateException("An Supplier has already been provided");
		}

		this.nioCallback = nioCallback;
		return this;
	}

	@Override
	public BuiltClientRequest withNioCallback(Supplier nioCallbackSupplier) {
		if (nioCallback != null) {
			throw new IllegalStateException("An NioCallback has already been provided");
		}

		this.nioCallbackSupplier = nioCallbackSupplier;
		return this;
	}

	public BuiltClientRequest withExternalEventTrigger(Supplier externalEventTriggerSupplier) {
		this.externalEventTriggerSupplier = externalEventTriggerSupplier;
		return this;
	}


	@Override
	public BuiltClientRequestWithBody withUploadCallback(UploadCallback uploadCallback) {
		if (uploadCallbackSupplier != null) {
			throw new IllegalStateException("An UploadCallback supplier has already been provided");
		}
		this.uploadCallback = uploadCallback;
		return this;
	}

	@Override
	public BuiltClientRequestWithBody withUploadCallback(Supplier uploadCallbackSupplier) {
		if (uploadCallback != null) {
			throw new IllegalStateException("An UploadCallback has already been provided");
		}
		this.uploadCallbackSupplier = uploadCallbackSupplier;
		return this;
	}

	@Override
	public CompletableFuture> execute() {
		HttpCallback httpCallback = getHttpCallback();

		String completeUri = UriUtil.getUriWithParameters(uri, queryParameters);

		ServerInfo serverInfo = null;
		try {
			serverInfo = ServerInfo.buildFromUri(completeUri);
		} catch (URISyntaxException e) {
			return dispatchError(httpCallback, e);
		}

		String relativePath = UriUtil.getRelativeUri(completeUri);


		DefaultHttpRequest defaultHttpRequest = new DefaultHttpRequest(httpVersion, httpMethod, relativePath);

		HttpBody httpBody = null;

		if (requestBodyBuilder != null) {
			httpBody = requestBodyBuilder.createHttpBody(contentType, bodyCharset);
		}

		NettyHttpClientRequest nettyHttpClientRequest = new NettyHttpClientRequest<>(serverInfo, defaultHttpRequest, httpBody);

		HttpHeaders headers = nettyHttpClientRequest.getNettyHeaders();

		for (Param headerParameter : headerParameters) {
			headers.add(headerParameter.getName(), headerParameter.getValue());
		}


		if (acceptCompressedResponse && !headers.contains(HttpHeaderNames.ACCEPT_ENCODING)) {
			headers.set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP + "," + HttpHeaderValues.DEFLATE);
		}

		if (httpBody != null) {
			if (httpBody.getContentLength() < 0) {
				headers.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
			} else {
				headers.set(HttpHeaderNames.CONTENT_LENGTH, String.valueOf(httpBody.getContentLength()));
			}

			String contentType = httpBody.getContentType();
			if (contentType != null) {
				Charset characterEncoding = httpBody.getCharacterEncoding();
				if (characterEncoding != null && !contentType.contains("charset=")) {
					contentType = contentType + ";charset=" + characterEncoding.name();
				}
				headers.set(HttpHeaderNames.CONTENT_TYPE, contentType);
			}

		}


		if (!headers.contains(HttpHeaderNames.ACCEPT)) {
			headers.set(HttpHeaderNames.ACCEPT, "*/*");
		}

		if (!headers.contains(HttpHeaderNames.USER_AGENT)) {
			headers.set(HttpHeaderNames.USER_AGENT, defaultUserAgent);
		}

		if (!serverInfo.isWebSocket()) {
			nettyHttpClientRequest.setKeepAlive(keepAlive);
		}

		return httpClientCaller.execute(httpMethod, nettyHttpClientRequest, httpCallback, getNioCallback(), getUploadCallback(), responseBodyConsumer.get(),
			callbackExecutor, getExternalEventTrigger(), customCallbackSubscriber, idleTimeoutMillis, totalRequestTimeoutMillis, followRedirects, keepAlive);
	}


	private NioCallback getNioCallback() {
		NioCallback nioCallback = this.nioCallback;
		if (nioCallbackSupplier != null) {
			nioCallback = nioCallbackSupplier.get();
		}
		return nioCallback;
	}

	private UploadCallback getUploadCallback() {
		UploadCallback uploadCallback = this.uploadCallback;
		if (uploadCallbackSupplier != null) {
			uploadCallback = uploadCallbackSupplier.get();
		}
		return uploadCallback;
	}

	private HttpCallback getHttpCallback() {
		HttpCallback httpCallback = this.httpCallback;
		if (httpCallbackSupplier != null) {
			httpCallback = httpCallbackSupplier.get();
		}
		return httpCallback;
	}

	private ExternalEventTrigger getExternalEventTrigger() {
		ExternalEventTrigger externalEventTrigger = null;
		if (externalEventTriggerSupplier != null) {
			externalEventTrigger = externalEventTriggerSupplier.get();
		}
		return externalEventTrigger;
	}

	private CompletableFuture> dispatchError(final HttpCallback httpCallback, final URISyntaxException e) {
		if (httpCallback != null) {
            callbackExecutor.execute(() -> httpCallback.onError(e));
        }

		return ResponseFuture.error(e);
	}

	public int getIdleTimeoutMillis() {
		return idleTimeoutMillis;
	}

	public int getTotalRequestTimeoutMillis() {
		return totalRequestTimeoutMillis;
	}

	public boolean isFollowRedirects() {
		return followRedirects;
	}

	public boolean isAcceptCompressedResponse() {
		return acceptCompressedResponse;
	}

	public boolean isKeepAlive() {
		return keepAlive;
	}


	public BuiltClientRequest withCustomCallbackSupplier(CustomCallbackSubscriber customCallbackSubscriber) {
		this.customCallbackSubscriber = customCallbackSubscriber;
		return this;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy