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

io.muserver.murp.HttpClientBuilder Maven / Gradle / Ivy

package io.muserver.murp;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.util.HttpCookieStore;
import org.eclipse.jetty.util.ssl.SslContextFactory;

/**
 * A builder for a Jetty HTTP Client that is suitable for use in a reverse proxy.
 */
public class HttpClientBuilder {

    private int requestBufferSize = 16 * 1024;
    private long idleTimeoutMillis = 60000;
    private long connectTimeoutMillis = 15000;
    private long addressResolutionTimeoutMillis = 15000;
    private int maxConnectionsPerDestination = 256;
    private SslContextFactory sslContextFactory;

    /**
     * @param idleTimeoutMillis the max time, in milliseconds, a connection can be idle (that is, without traffic of bytes in either direction).
     *                          The default is 60 seconds.
     * @return This builder
     * @see HttpClient#setIdleTimeout(long)
     */
    public HttpClientBuilder withIdleTimeoutMillis(long idleTimeoutMillis) {
        this.idleTimeoutMillis = idleTimeoutMillis;
        return this;
    }

    /**
     * @param connectTimeoutMillis the max time, in milliseconds, a connection can take to connect to destinations. The default is 15 seconds.
     * @return This builder
     * @see HttpClient#setConnectTimeout(long)
     */
    public HttpClientBuilder withConnectTimeoutMillis(long connectTimeoutMillis) {
        this.connectTimeoutMillis = connectTimeoutMillis;
        return this;
    }

    /**
     * Sets the maximum size of request headers that can be proxied. The default is 16384 bytes.
     * @param maxSizeInBytes The max size in bytes of the request headers on proxy calls to the target
     * @return This builder
     */
    public HttpClientBuilder withMaxRequestHeadersSize(int maxSizeInBytes) {
        this.requestBufferSize = maxSizeInBytes;
        return this;
    }

    /**
     * @param addressResolutionTimeoutMillis the socket address resolution timeout. The default is 15 seconds.
     * @return This builder
     * @see HttpClient#setAddressResolutionTimeout(long)
     */
    public HttpClientBuilder withAddressResolutionTimeoutMillis(long addressResolutionTimeoutMillis) {
        this.addressResolutionTimeoutMillis = addressResolutionTimeoutMillis;
        return this;
    }

    /**
     * @param maxConnectionsPerDestination the max number of connections to open to each destination. The default is 256.
     * @return This builder
     * @see HttpClient#setMaxConnectionsPerDestination(int)
     */
    public HttpClientBuilder withMaxConnectionsPerDestination(int maxConnectionsPerDestination) {
        this.maxConnectionsPerDestination = maxConnectionsPerDestination;
        return this;
    }

    /**
     * The SSL Context Factory to use. The default one trusts all servers.
     * @param sslContextFactory The SSL Context factory to use, or null for the default
     * @return This builder
     */
    public HttpClientBuilder withSslContextFactory(SslContextFactory sslContextFactory) {
        this.sslContextFactory = sslContextFactory;
        return this;
    }

    /**
     * @return a new client builder with reasonable defaults
     */
    public static HttpClientBuilder httpClient() {
        return new HttpClientBuilder();
    }

    /**
     * Creates and starts an HTTP Client that is suitable for use in a reverse proxy
     * @return A started Jetty HttpClient
     */
    public HttpClient build() {

        int selectors = Math.max(1, Runtime.getRuntime().availableProcessors() / 2);

        SslContextFactory scf = sslContextFactory != null ? sslContextFactory : new SslContextFactory(true);

        HttpClient client = new HttpClient(new HttpClientTransportOverHTTP(selectors), scf);
        client.setFollowRedirects(false);
        client.setCookieStore(new HttpCookieStore.Empty());
        client.setMaxConnectionsPerDestination(maxConnectionsPerDestination);
        client.setAddressResolutionTimeout(addressResolutionTimeoutMillis);
        client.setConnectTimeout(connectTimeoutMillis);
        client.setIdleTimeout(idleTimeoutMillis);
        client.setRequestBufferSize(requestBufferSize);
        client.setUserAgentField(null);
        try {
            client.start();
        } catch (Exception e) {
            throw new RuntimeException("Error while starting HTTP Client for reverse proxy", e);
        }

        client.getContentDecoderFactories().clear();
        client.getProtocolHandlers().clear();

        return client;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy