This commit is contained in:
Looly 2023-03-11 19:42:04 +08:00
parent fb7e88515a
commit d80747f9d5
13 changed files with 358 additions and 227 deletions

View File

@ -13,6 +13,7 @@ import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* {@link SSLContext}构建器可以自定义<br>
* <ul>

View File

@ -1,4 +1,4 @@
package cn.hutool.http.ssl;
package cn.hutool.core.net.ssl;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
@ -10,6 +10,11 @@ import javax.net.ssl.SSLSession;
*/
public class TrustAnyHostnameVerifier implements HostnameVerifier {
/**
* 单例对象
*/
public static TrustAnyHostnameVerifier INSTANCE = new TrustAnyHostnameVerifier();
@Override
public boolean verify(final String hostname, final SSLSession session) {
return true;// 直接返回true

View File

@ -1,12 +1,8 @@
package cn.hutool.http.client;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.net.ssl.SSLUtil;
import cn.hutool.http.HttpGlobalConfig;
import cn.hutool.http.ssl.TrustAnySSLInfo;
import cn.hutool.http.ssl.SSLInfo;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import java.net.InetSocketAddress;
import java.net.Proxy;
@ -35,14 +31,7 @@ public class ClientConfig {
*/
private int readTimeout;
/**
* HostnameVerifier用于HTTPS安全连接
*/
private HostnameVerifier hostnameVerifier;
/**
* SSLSocketFactory用于HTTPS安全连接
*/
private SSLSocketFactory socketFactory;
private SSLInfo sslInfo;
/**
* 是否禁用缓存
*/
@ -58,8 +47,7 @@ public class ClientConfig {
public ClientConfig() {
connectionTimeout = HttpGlobalConfig.getTimeout();
readTimeout = HttpGlobalConfig.getTimeout();
hostnameVerifier = TrustAnySSLInfo.TRUST_ANY_HOSTNAME_VERIFIER;
socketFactory = TrustAnySSLInfo.DEFAULT_SSF;
sslInfo = SSLInfo.TRUST_ANY;
}
/**
@ -123,34 +111,12 @@ public class ClientConfig {
}
/**
* 获取域名验证器
* 获取SSLInfo
*
* @return 域名验证器
* @return SSLInfo
*/
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}
/**
* 设置域名验证器<br>
* 只针对HTTPS请求如果不设置不做验证所有域名被信任
*
* @param hostnameVerifier HostnameVerifier
* @return this
*/
public ClientConfig setHostnameVerifier(final HostnameVerifier hostnameVerifier) {
// 验证域
this.hostnameVerifier = hostnameVerifier;
return this;
}
/**
* 获取SSLSocketFactory
*
* @return SSLSocketFactory
*/
public SSLSocketFactory getSocketFactory() {
return socketFactory;
public SSLInfo getSslInfo() {
return this.sslInfo;
}
/**
@ -158,33 +124,11 @@ public class ClientConfig {
* 只针对HTTPS请求如果不设置使用默认的SSLSocketFactory<br>
* 默认SSLSocketFactory为SSLSocketFactoryBuilder.create().build();
*
* @param ssf SSLScketFactory
* @param sslInfo SSLInfo
* @return this
*/
public ClientConfig setSocketFactory(final SSLSocketFactory ssf) {
this.socketFactory = ssf;
return this;
}
/**
* 设置HTTPS安全连接协议只针对HTTPS请求可以使用的协议包括<br>
* 此方法调用后{@link #setSocketFactory(SSLSocketFactory)} 将被覆盖
*
* <pre>
* 1. TLSv1.2
* 2. TLSv1.1
* 3. SSLv3
* ...
* </pre>
*
* @param protocol 协议
* @return this
* @see SSLUtil#createTrustAnySSLContext(String)
* @see #setSocketFactory(SSLSocketFactory)
*/
public ClientConfig setSSLProtocol(final String protocol) {
Assert.notBlank(protocol, "protocol must be not blank!");
setSocketFactory(SSLUtil.createTrustAnySSLContext(protocol).getSocketFactory());
public ClientConfig setSSLInfo(final SSLInfo sslInfo) {
this.sslInfo = sslInfo;
return this;
}

View File

@ -10,19 +10,26 @@ import cn.hutool.http.client.ClientEngine;
import cn.hutool.http.client.Request;
import cn.hutool.http.client.Response;
import cn.hutool.http.client.body.HttpBody;
import cn.hutool.http.ssl.SSLInfo;
import org.apache.http.Header;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import java.io.IOException;
import java.net.URI;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* Apache HttpClient5的HTTP请求引擎
@ -38,7 +45,8 @@ public class HttpClient4Engine implements ClientEngine {
/**
* 构造
*/
public HttpClient4Engine() {}
public HttpClient4Engine() {
}
@Override
public HttpClient4Engine setConfig(final ClientConfig config) {
@ -77,33 +85,27 @@ public class HttpClient4Engine implements ClientEngine {
/**
* 初始化引擎
*/
private void initEngine(){
if(null != this.engine){
private void initEngine() {
if (null != this.engine) {
return;
}
RequestConfig requestConfig = null;
if(null != this.config){
final RequestConfig.Builder builder = RequestConfig.custom();
final int connectionTimeout = this.config.getConnectionTimeout();
if(connectionTimeout > 0){
builder.setConnectTimeout(connectionTimeout);
builder.setConnectionRequestTimeout(connectionTimeout);
}
final int readTimeout = this.config.getReadTimeout();
if(readTimeout > 0){
builder.setSocketTimeout(readTimeout);
final HttpClientBuilder clientBuilder = HttpClients.custom();
final ClientConfig config = this.config;
if (null != config) {
// SSL配置
final SSLInfo sslInfo = config.getSslInfo();
if (null != sslInfo) {
clientBuilder.setSSLSocketFactory(buildSocketFactory(sslInfo));
}
requestConfig = builder.build();
clientBuilder.setDefaultRequestConfig(buildRequestConfig(config));
}
this.engine = HttpClients.custom()
// 设置默认头信息
.setDefaultRequestConfig(requestConfig)
.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers()))
.build();
// 设置默认头信息
clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers()));
this.engine = clientBuilder.build();
}
/**
@ -151,4 +153,41 @@ public class HttpClient4Engine implements ClientEngine {
headersMap.forEach((k, v1) -> v1.forEach((v2) -> result.add(new BasicHeader(k, v2))));
return result;
}
/**
* 支持SSL
*
* @return SSLConnectionSocketFactory
*/
private static SSLConnectionSocketFactory buildSocketFactory(final SSLInfo sslInfo) {
return new SSLConnectionSocketFactory(
sslInfo.getSslContext(),
sslInfo.getProtocols(),
null,
sslInfo.getHostnameVerifier());
}
/**
* 构建请求配置包括连接请求超时和响应读取超时
*
* @param config {@link ClientConfig}
* @return {@link RequestConfig}
*/
private static RequestConfig buildRequestConfig(final ClientConfig config) {
// 请求配置
final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
// 连接超时
final int connectionTimeout = config.getConnectionTimeout();
if (connectionTimeout > 0) {
requestConfigBuilder.setConnectTimeout(connectionTimeout);
requestConfigBuilder.setConnectionRequestTimeout(connectionTimeout);
}
final int readTimeout = config.getReadTimeout();
if (readTimeout > 0) {
requestConfigBuilder.setSocketTimeout(readTimeout);
}
return requestConfigBuilder.build();
}
}

View File

@ -11,12 +11,14 @@ import cn.hutool.http.client.ClientEngine;
import cn.hutool.http.client.Request;
import cn.hutool.http.client.Response;
import cn.hutool.http.client.body.HttpBody;
import cn.hutool.http.ssl.SSLInfo;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.core5.http.ClassicHttpRequest;
@ -45,7 +47,8 @@ public class HttpClient5Engine implements ClientEngine {
/**
* 构造
*/
public HttpClient5Engine() {}
public HttpClient5Engine() {
}
@Override
public HttpClient5Engine setConfig(final ClientConfig config) {
@ -84,47 +87,25 @@ public class HttpClient5Engine implements ClientEngine {
/**
* 初始化引擎
*/
private void initEngine(){
if(null != this.engine){
private void initEngine() {
if (null != this.engine) {
return;
}
// 连接配置
final PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
.setSslContext(SSLUtil.createTrustAnySSLContext()).build());
final HttpClientBuilder clientBuilder = HttpClients.custom();
// 请求配置
RequestConfig requestConfig = null;
if(null != this.config){
final int connectionTimeout = this.config.getConnectionTimeout();
if(connectionTimeout > 0){
connectionManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
.setConnectTimeout(connectionTimeout, TimeUnit.MILLISECONDS).build());
}
final RequestConfig.Builder builder = RequestConfig.custom();
if(connectionTimeout > 0){
builder.setConnectionRequestTimeout(connectionTimeout, TimeUnit.MILLISECONDS);
}
final int readTimeout = this.config.getReadTimeout();
if(readTimeout > 0){
builder.setResponseTimeout(readTimeout, TimeUnit.MILLISECONDS);
}
requestConfig = builder.build();
final ClientConfig config = this.config;
if (null != config) {
clientBuilder.setConnectionManager(buildConnectionManager(config));
clientBuilder.setDefaultRequestConfig(buildRequestConfig(config));
}
final HttpClientBuilder builder = HttpClients.custom()
.setConnectionManager(connectionManagerBuilder.build())
.setDefaultRequestConfig(requestConfig)
// 设置默认头信息
.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers()));
// 设置默认头信息
clientBuilder.setDefaultHeaders(toHeaderList(GlobalHeaders.INSTANCE.headers()));
// TODO 设置代理
this.engine = builder.build();
this.engine = clientBuilder.build();
}
/**
@ -167,4 +148,54 @@ public class HttpClient5Engine implements ClientEngine {
headersMap.forEach((k, v1) -> v1.forEach((v2) -> result.add(new BasicHeader(k, v2))));
return result;
}
/**
* 构建连接管理器包括SSL配置和连接超时配置
*
* @param config {@link ClientConfig}
* @return {@link PoolingHttpClientConnectionManager}
*/
private static PoolingHttpClientConnectionManager buildConnectionManager(final ClientConfig config) {
final PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder.create();
// SSL配置
final SSLInfo sslInfo = config.getSslInfo();
if (null != sslInfo) {
connectionManagerBuilder.setSSLSocketFactory(SSLConnectionSocketFactoryBuilder.create()
.setTlsVersions(sslInfo.getProtocols())
.setSslContext(sslInfo.getSslContext())
.setHostnameVerifier(sslInfo.getHostnameVerifier())
.build());
}
// 连接超时配置
final int connectionTimeout = config.getConnectionTimeout();
if (connectionTimeout > 0) {
connectionManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
.setSocketTimeout(connectionTimeout, TimeUnit.MILLISECONDS)
.setConnectTimeout(connectionTimeout, TimeUnit.MILLISECONDS).build());
}
return connectionManagerBuilder.build();
}
/**
* 构建请求配置包括连接请求超时和响应读取超时
*
* @param config {@link ClientConfig}
* @return {@link RequestConfig}
*/
private static RequestConfig buildRequestConfig(final ClientConfig config) {
final int connectionTimeout = config.getConnectionTimeout();
// 请求配置
final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
if (connectionTimeout > 0) {
requestConfigBuilder.setConnectionRequestTimeout(connectionTimeout, TimeUnit.MILLISECONDS);
}
final int readTimeout = config.getReadTimeout();
if (readTimeout > 0) {
requestConfigBuilder.setResponseTimeout(readTimeout, TimeUnit.MILLISECONDS);
}
return requestConfigBuilder.build();
}
}

View File

@ -7,11 +7,9 @@ import cn.hutool.core.util.ObjUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.client.HeaderOperation;
import cn.hutool.http.meta.Method;
import cn.hutool.http.ssl.TrustAnySSLInfo;
import cn.hutool.http.ssl.SSLInfo;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -196,23 +194,23 @@ public class HttpConnection implements HeaderOperation<HttpConnection> {
}
/**
* 设置https请求参数<br>
* 设置https中SSL相关请求参数<br>
* 有些时候htts请求会出现com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl的实现此为sun内部api按照普通http请求处理
*
* @param hostnameVerifier 域名验证器非https传入null
* @param ssf SSLSocketFactory非https传入null
* @param sslInfo {@link SSLInfo}
* @return this
* @throws HttpException KeyManagementException和NoSuchAlgorithmException异常包装
* @since 6.0.0
*/
public HttpConnection setHttpsInfo(final HostnameVerifier hostnameVerifier, final SSLSocketFactory ssf) throws HttpException {
public HttpConnection setSSLInfo(final SSLInfo sslInfo) throws HttpException {
final HttpURLConnection conn = this.conn;
if (conn instanceof HttpsURLConnection) {
// Https请求
final HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
// 验证域
httpsConn.setHostnameVerifier(ObjUtil.defaultIfNull(hostnameVerifier, TrustAnySSLInfo.TRUST_ANY_HOSTNAME_VERIFIER));
httpsConn.setSSLSocketFactory(ObjUtil.defaultIfNull(ssf, TrustAnySSLInfo.DEFAULT_SSF));
httpsConn.setHostnameVerifier(ObjUtil.defaultIfNull(sslInfo.getHostnameVerifier(), SSLInfo.TRUST_ANY.getHostnameVerifier()));
httpsConn.setSSLSocketFactory(ObjUtil.defaultIfNull(sslInfo.getSocketFactory(), SSLInfo.TRUST_ANY.getSocketFactory()));
}
return this;

View File

@ -129,7 +129,7 @@ public class JdkClientEngine implements ClientEngine {
.setConnectTimeout(config.getConnectionTimeout())
.setReadTimeout(config.getReadTimeout())
.setMethod(message.method())//
.setHttpsInfo(config.getHostnameVerifier(), config.getSocketFactory())
.setSSLInfo(config.getSslInfo())
// 关闭JDK自动转发采用手动转发方式
.setInstanceFollowRedirects(false)
.setChunkedStreamingMode(message.isChunked() ? 4096 : -1)

View File

@ -6,6 +6,7 @@ import cn.hutool.http.client.ClientConfig;
import cn.hutool.http.client.ClientEngine;
import cn.hutool.http.client.Request;
import cn.hutool.http.client.Response;
import cn.hutool.http.ssl.SSLInfo;
import okhttp3.OkHttpClient;
import okhttp3.internal.http.HttpMethod;
@ -71,15 +72,34 @@ public class OkHttpEngine implements ClientEngine {
return;
}
final ClientConfig config = ObjUtil.defaultIfNull(this.config, ClientConfig::of);
final OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(config.getConnectionTimeout(), TimeUnit.MILLISECONDS)
.readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS);
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
// 设置代理
final Proxy proxy = config.getProxy();
if(null != proxy){
builder.proxy(proxy);
final ClientConfig config = this.config;
if (null != config) {
// 连接超时
final int connectionTimeout = config.getConnectionTimeout();
if (connectionTimeout > 0) {
builder.connectTimeout(connectionTimeout, TimeUnit.MILLISECONDS);
}
// 读写超时
final int readTimeout = config.getReadTimeout();
if (readTimeout > 0) {
// 读写共用读取超时
builder.readTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS)
.writeTimeout(config.getReadTimeout(), TimeUnit.MILLISECONDS);
}
// SSL
final SSLInfo sslInfo = config.getSslInfo();
if(null != sslInfo){
builder.sslSocketFactory(sslInfo.getSocketFactory(), sslInfo.getTrustManager());
}
// 设置代理
final Proxy proxy = config.getProxy();
if (null != proxy) {
builder.proxy(proxy);
}
}
this.client = builder.build();

View File

@ -1,30 +0,0 @@
package cn.hutool.http.ssl;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.net.ssl.SSLProtocols;
/**
* 兼容android低版本SSL连接<br>
* 在测试HttpUrlConnection的时候发现一部分手机无法连接[GithubPage]
*
* <p>
* 最后发现原来是某些SSL协议没有开启
*
* @author MikaGuraNTK
*/
public class AndroidSupportSSLFactory extends CustomProtocolsSSLFactory {
// Android低版本不重置的话某些SSL访问就会失败
private static final String[] protocols = {
SSLProtocols.SSLv3, SSLProtocols.TLSv1, SSLProtocols.TLSv11, SSLProtocols.TLSv12};
/**
* 构造
*
* @throws IORuntimeException IO异常
*/
public AndroidSupportSSLFactory() throws IORuntimeException {
super(protocols);
}
}

View File

@ -17,68 +17,68 @@ import java.net.Socket;
*/
public class CustomProtocolsSSLFactory extends SSLSocketFactory {
private final SSLSocketFactory raw;
private final String[] protocols;
private final SSLSocketFactory base;
/**
* 构造
*
* @param factory {@link SSLSocketFactory}
* @param protocols 支持协议列表
* @throws IORuntimeException IO异常
*/
public CustomProtocolsSSLFactory(final String... protocols) throws IORuntimeException {
public CustomProtocolsSSLFactory(final SSLSocketFactory factory, final String... protocols) {
this.raw = factory;
this.protocols = protocols;
this.base = SSLUtil.createTrustAnySSLContext(null).getSocketFactory();
}
@Override
public String[] getDefaultCipherSuites() {
return base.getDefaultCipherSuites();
return raw.getDefaultCipherSuites();
}
@Override
public String[] getSupportedCipherSuites() {
return base.getSupportedCipherSuites();
return raw.getSupportedCipherSuites();
}
@Override
public Socket createSocket() throws IOException {
final SSLSocket sslSocket = (SSLSocket) base.createSocket();
final SSLSocket sslSocket = (SSLSocket) raw.createSocket();
resetProtocols(sslSocket);
return sslSocket;
}
@Override
public SSLSocket createSocket(final Socket s, final String host, final int port, final boolean autoClose) throws IOException {
final SSLSocket socket = (SSLSocket) base.createSocket(s, host, port, autoClose);
final SSLSocket socket = (SSLSocket) raw.createSocket(s, host, port, autoClose);
resetProtocols(socket);
return socket;
}
@Override
public Socket createSocket(final String host, final int port) throws IOException {
final SSLSocket socket = (SSLSocket) base.createSocket(host, port);
final SSLSocket socket = (SSLSocket) raw.createSocket(host, port);
resetProtocols(socket);
return socket;
}
@Override
public Socket createSocket(final String host, final int port, final InetAddress localHost, final int localPort) throws IOException {
final SSLSocket socket = (SSLSocket) base.createSocket(host, port, localHost, localPort);
final SSLSocket socket = (SSLSocket) raw.createSocket(host, port, localHost, localPort);
resetProtocols(socket);
return socket;
}
@Override
public Socket createSocket(final InetAddress host, final int port) throws IOException {
final SSLSocket socket = (SSLSocket) base.createSocket(host, port);
final SSLSocket socket = (SSLSocket) raw.createSocket(host, port);
resetProtocols(socket);
return socket;
}
@Override
public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddress, final int localPort) throws IOException {
final SSLSocket socket = (SSLSocket) base.createSocket(address, port, localAddress, localPort);
final SSLSocket socket = (SSLSocket) raw.createSocket(address, port, localAddress, localPort);
resetProtocols(socket);
return socket;
}

View File

@ -1,15 +0,0 @@
package cn.hutool.http.ssl;
/**
* 默认的SSLSocketFactory
*
* @author Looly
* @since 5.1.2
*/
public class DefaultSSLFactory extends CustomProtocolsSSLFactory {
/**
* 构造
*/
public DefaultSSLFactory() {}
}

View File

@ -0,0 +1,169 @@
package cn.hutool.http.ssl;
import cn.hutool.core.net.ssl.SSLProtocols;
import cn.hutool.core.net.ssl.SSLUtil;
import cn.hutool.core.net.ssl.TrustAnyHostnameVerifier;
import cn.hutool.core.net.ssl.TrustAnyTrustManager;
import cn.hutool.core.text.StrUtil;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
/**
* HTTP请求中SSL相关信息包括
* <ul>
* <li>{@link HostnameVerifier}</li>
* <li>{@link SSLContext}</li>
* <li>{@link X509TrustManager}</li>
* </ul>
*
* @author looly
* @since 6.0.0
*/
public class SSLInfo {
/**
* 默认{@code SSLInfo}全部为{@code null}使用客户端引擎默认配置
*/
public static final SSLInfo DEFAULT = SSLInfo.of();
/**
* 信任所有的{@code SSLInfo}
*/
public static final SSLInfo TRUST_ANY = SSLInfo.of()
.setHostnameVerifier(TrustAnyHostnameVerifier.INSTANCE)
.setSslContext(SSLUtil.createTrustAnySSLContext())
.setTrustManager(TrustAnyTrustManager.INSTANCE);
/**
* 构建{@code SSLInfo}
*
* @return {@code SSLInfo}
*/
public static SSLInfo of() {
return new SSLInfo();
}
/**
* 支持的协议类型
*/
private String[] protocols;
/**
* HostnameVerifier用于HTTPS安全连接
*/
private HostnameVerifier hostnameVerifier;
/**
* SSLContext用于HTTPS安全连接
*/
private SSLContext sslContext;
/**
* 信任管理器
*/
private X509TrustManager trustManager;
/**
* 构造
*/
public SSLInfo() {
if (StrUtil.equalsIgnoreCase("dalvik", System.getProperty("java.vm.name"))) {
//兼容android低版本SSL连接
this.protocols = new String[]{
SSLProtocols.SSLv3,
SSLProtocols.TLSv1,
SSLProtocols.TLSv11,
SSLProtocols.TLSv12};
}
}
/**
* 获取所有支持的协议
*
* @return 协议列表
*/
public String[] getProtocols() {
return protocols;
}
/**
* 设置协议列表
*
* @param protocols 协议列表
* @return this
*/
public SSLInfo setProtocols(final String... protocols) {
this.protocols = protocols;
return this;
}
/**
* 获取{@link HostnameVerifier}
*
* @return {@link HostnameVerifier}
*/
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}
/**
* 设置{@link HostnameVerifier}信任所有则使用{@link cn.hutool.core.net.ssl.TrustAnyHostnameVerifier}
*
* @param hostnameVerifier {@link HostnameVerifier}
* @return this
*/
public SSLInfo setHostnameVerifier(final HostnameVerifier hostnameVerifier) {
this.hostnameVerifier = hostnameVerifier;
return this;
}
/**
* 获取{@link SSLContext}
*
* @return {@link SSLContext}
*/
public SSLContext getSslContext() {
return sslContext;
}
/**
* 设置{@link SSLContext}可以使用{@link cn.hutool.core.net.ssl.SSLContextBuilder}构建
*
* @param sslContext {@link SSLContext}
* @return this
*/
public SSLInfo setSslContext(final SSLContext sslContext) {
this.sslContext = sslContext;
return this;
}
/**
* 获取{@link X509TrustManager}
*
* @return {@link X509TrustManager}
*/
public X509TrustManager getTrustManager() {
return trustManager;
}
/**
* 设置{@link X509TrustManager}新人所有则使用{@link cn.hutool.core.net.ssl.TrustAnyTrustManager}
*
* @param trustManager {@link X509TrustManager}
* @return this
*/
public SSLInfo setTrustManager(final X509TrustManager trustManager) {
this.trustManager = trustManager;
return this;
}
/**
* 获取{@link SSLSocketFactory}
*
* @return {@link SSLSocketFactory}
*/
public SSLSocketFactory getSocketFactory() {
final SSLSocketFactory factory = this.sslContext.getSocketFactory();
return new CustomProtocolsSSLFactory(factory, this.protocols);
}
}

View File

@ -1,31 +0,0 @@
package cn.hutool.http.ssl;
import cn.hutool.core.text.StrUtil;
import javax.net.ssl.SSLSocketFactory;
/**
* 新任所有SSL配置
*
* @author looly
*/
public class TrustAnySSLInfo {
/**
* 默认信任全部的域名校验器
*/
public static final TrustAnyHostnameVerifier TRUST_ANY_HOSTNAME_VERIFIER;
/**
* 默认的SSLSocketFactory区分安卓
*/
public static final SSLSocketFactory DEFAULT_SSF;
static {
TRUST_ANY_HOSTNAME_VERIFIER = new TrustAnyHostnameVerifier();
if (StrUtil.equalsIgnoreCase("dalvik", System.getProperty("java.vm.name"))) {
// 兼容android低版本SSL连接
DEFAULT_SSF = new AndroidSupportSSLFactory();
} else {
DEFAULT_SSF = new DefaultSSLFactory();
}
}
}