package log;

import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.concurrent.TimeUnit;

public class HttpClientInit {
    /**
     * 最大连接数
     */
    public final static int MAX_TOTAL_CONNECTIONS = 1200;
    /**
     * 获取连接的最大等待时间
     */
    public final static int WAIT_TIMEOUT = 30000;
    /**
     * 每个路由最大连接数
     */
    public final static int MAX_ROUTE_CONNECTIONS = 400;
    /**
     * 连接超时时间
     */
    public final static int CONNECT_TIMEOUT = 10000;


    public static CloseableHttpClient getHttpClient() {

        HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 3) {
                    // Do not retry if over max retry count
                    return false;
                }
                if (exception instanceof InterruptedIOException) {
                    // Timeout
                    return true;
                }
                if (exception instanceof UnknownHostException) {
                    // Unknown host
                    return false;
                }
                if (exception instanceof ConnectTimeoutException) {
                    return true;
                }
                if (exception instanceof SSLException) {
                    return true;
                }
                if (exception instanceof SSLPeerUnverifiedException) {
                    // SSL handshake exception
                    System.out.println("https证书异常");
                    return true;
                }
                if (exception instanceof SocketTimeoutException) {
                    // SSL handshake exception
                    System.out.println("socket超时异常");
                    return true;
                }
                if (exception instanceof NoHttpResponseException) {
                    // SSL handshake exception
                    System.out.println("http无响应异常");
                    return true;
                }
                if (exception instanceof HttpHostConnectException) {
                    // SSL handshake exception
                    System.out.println("http主机连接异常");
                    return true;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                if (idempotent) {
                    return true;
                }
                return false;
            }
        };

        RequestConfig requestConfig = RequestConfig.custom()
                // 获取连接超时时间
                .setConnectionRequestTimeout(CONNECT_TIMEOUT)
                // 请求超时时间
                .setConnectTimeout(CONNECT_TIMEOUT)
                // 响应超时时间
                .setSocketTimeout(CONNECT_TIMEOUT)
                .build();

        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        cm.setDefaultMaxPerRoute(MAX_ROUTE_CONNECTIONS);

        //单个路由设置其连接大小
        //cm.setMaxPerRoute(new HttpRoute(new HttpHost("jd.com",80)), 100);
        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .setRetryHandler(retryHandler)
                .setConnectionManager(cm)
                //定期回收空闲连接
                .evictExpiredConnections()
                .setConnectionTimeToLive(1, TimeUnit.HOURS)
                .build();
        return httpClient;

    }


}
