mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix ssl bug
This commit is contained in:
parent
f3d63f85c3
commit
f76519351d
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Hutool Team and hutool.cn
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.http.client.engine.httpclient4;
|
||||
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.dromara.hutool.core.lang.builder.Builder;
|
||||
import org.dromara.hutool.http.ssl.SSLInfo;
|
||||
|
||||
/**
|
||||
* HttpClient4连接工厂注册器构建器
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class ConnectionSocketFactoryRegistryBuilder implements Builder<Registry<ConnectionSocketFactory>> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 创建
|
||||
*
|
||||
* @return {@code ConnectionSocketFactoryRegistryBuilder}
|
||||
*/
|
||||
public static ConnectionSocketFactoryRegistryBuilder of() {
|
||||
return new ConnectionSocketFactoryRegistryBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建默认的连接工厂注册器,默认支持SSL
|
||||
*
|
||||
* @param sslInfo SSL配置,{@code null}表示使用默认配置,即{@link SSLConnectionSocketFactory#getSocketFactory()}
|
||||
* @return {@code Registry<ConnectionSocketFactory>}
|
||||
*/
|
||||
public static Registry<ConnectionSocketFactory> build(final SSLInfo sslInfo) {
|
||||
return of().registerPlainHttp().registerHttps(sslInfo).build();
|
||||
}
|
||||
|
||||
private final RegistryBuilder<ConnectionSocketFactory> builder;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*/
|
||||
public ConnectionSocketFactoryRegistryBuilder() {
|
||||
builder = RegistryBuilder.create();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册HTTP协议,使用默认的普通(非加密)连接工厂
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ConnectionSocketFactoryRegistryBuilder registerPlainHttp() {
|
||||
return registerHttp(PlainConnectionSocketFactory.getSocketFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册HTTP协议,使用默认的普通连接工厂
|
||||
*
|
||||
* @param socketFactory {@link ConnectionSocketFactory}
|
||||
* @return this
|
||||
*/
|
||||
public ConnectionSocketFactoryRegistryBuilder registerHttp(final ConnectionSocketFactory socketFactory) {
|
||||
return register("http", socketFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册HTTPS协议
|
||||
*
|
||||
* @param sslInfo SSL配置,{@code null}表示使用默认配置,即{@link SSLConnectionSocketFactory#getSocketFactory()}
|
||||
* @return this
|
||||
*/
|
||||
public ConnectionSocketFactoryRegistryBuilder registerHttps(final SSLInfo sslInfo) {
|
||||
return register("https", buildSocketFactory(sslInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册连接工厂
|
||||
*
|
||||
* @param protocol 协议
|
||||
* @param socketFactory 连接工厂
|
||||
* @return this
|
||||
*/
|
||||
public ConnectionSocketFactoryRegistryBuilder register(final String protocol, final ConnectionSocketFactory socketFactory) {
|
||||
builder.register(protocol, socketFactory);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Registry<ConnectionSocketFactory> build() {
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持SSL
|
||||
*
|
||||
* @param sslInfo SSL配置,{@code null}表示使用默认配置,即{@link SSLConnectionSocketFactory#getSocketFactory()}
|
||||
* @return SSLConnectionSocketFactory
|
||||
*/
|
||||
private static SSLConnectionSocketFactory buildSocketFactory(final SSLInfo sslInfo) {
|
||||
if (null == sslInfo) {
|
||||
return SSLConnectionSocketFactory.getSocketFactory();
|
||||
}
|
||||
return new SSLConnectionSocketFactory(
|
||||
sslInfo.getSslContext(),
|
||||
sslInfo.getProtocols(),
|
||||
null,
|
||||
sslInfo.getHostnameVerifier());
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.BasicCredentialsProvider;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
@ -43,7 +42,6 @@ import org.dromara.hutool.http.client.Response;
|
||||
import org.dromara.hutool.http.client.cookie.InMemoryCookieStore;
|
||||
import org.dromara.hutool.http.client.engine.AbstractClientEngine;
|
||||
import org.dromara.hutool.http.proxy.ProxyInfo;
|
||||
import org.dromara.hutool.http.ssl.SSLInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.PasswordAuthentication;
|
||||
@ -112,13 +110,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
final HttpClientBuilder clientBuilder = HttpClients.custom();
|
||||
final ClientConfig config = ObjUtil.defaultIfNull(this.config, ApacheHttpClientConfig::of);
|
||||
|
||||
// SSL配置
|
||||
final SSLInfo sslInfo = config.getSslInfo();
|
||||
if (null != sslInfo) {
|
||||
clientBuilder.setSSLSocketFactory(buildSocketFactory(sslInfo));
|
||||
}
|
||||
|
||||
// 连接配置,包括连接池
|
||||
// 连接配置,包括SSL配置和连接池
|
||||
clientBuilder.setConnectionManager(buildConnectionManager(config));
|
||||
|
||||
// 实例级别默认请求配置
|
||||
@ -136,7 +128,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
setProxy(clientBuilder, config);
|
||||
|
||||
// Cookie管理
|
||||
if(config.isUseCookieManager()){
|
||||
if (config.isUseCookieManager()) {
|
||||
this.cookieStore = new InMemoryCookieStore();
|
||||
clientBuilder.setDefaultCookieStore(new HttpClient4CookieStore(this.cookieStore));
|
||||
}
|
||||
@ -155,19 +147,6 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 支持SSL
|
||||
*
|
||||
* @return SSLConnectionSocketFactory
|
||||
*/
|
||||
private static SSLConnectionSocketFactory buildSocketFactory(final SSLInfo sslInfo) {
|
||||
return new SSLConnectionSocketFactory(
|
||||
sslInfo.getSslContext(),
|
||||
sslInfo.getProtocols(),
|
||||
null,
|
||||
sslInfo.getHostnameVerifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建连接池管理器
|
||||
*
|
||||
@ -175,17 +154,20 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
* @return PoolingHttpClientConnectionManager
|
||||
*/
|
||||
private PoolingHttpClientConnectionManager buildConnectionManager(final ClientConfig config) {
|
||||
final PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager();
|
||||
final PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(
|
||||
// SSL配置,当config.getSslInfo()为null时,使用默认配置
|
||||
ConnectionSocketFactoryRegistryBuilder.build(config.getSslInfo())
|
||||
);
|
||||
|
||||
// 连接池配置
|
||||
if (config instanceof ApacheHttpClientConfig) {
|
||||
final ApacheHttpClientConfig apacheHttpClientConfig = (ApacheHttpClientConfig) config;
|
||||
final int maxTotal = apacheHttpClientConfig.getMaxTotal();
|
||||
if(maxTotal > 0){
|
||||
if (maxTotal > 0) {
|
||||
manager.setMaxTotal(maxTotal);
|
||||
}
|
||||
final int maxPerRoute = apacheHttpClientConfig.getMaxPerRoute();
|
||||
if(maxPerRoute > 0){
|
||||
if (maxPerRoute > 0) {
|
||||
manager.setDefaultMaxPerRoute(maxPerRoute);
|
||||
}
|
||||
}
|
||||
@ -234,7 +216,7 @@ public class HttpClient4Engine extends AbstractClientEngine {
|
||||
final ProxyInfo proxy = config.getProxy();
|
||||
if (null != proxy) {
|
||||
final ProxySelector proxySelector = proxy.getProxySelector();
|
||||
if(null != proxySelector){
|
||||
if (null != proxySelector) {
|
||||
clientBuilder.setRoutePlanner(new SystemDefaultRoutePlanner(proxySelector));
|
||||
}
|
||||
final PasswordAuthentication auth = proxy.getAuth();
|
||||
|
@ -0,0 +1,28 @@
|
||||
package org.dromara.hutool.http.client;
|
||||
|
||||
import org.dromara.hutool.core.lang.Console;
|
||||
import org.dromara.hutool.http.HttpGlobalConfig;
|
||||
import org.dromara.hutool.http.HttpUtil;
|
||||
import org.dromara.hutool.http.client.engine.ClientEngine;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class IssueIBC5N8Test {
|
||||
@Test
|
||||
@Disabled
|
||||
public void getBadSSLTest(){
|
||||
HttpGlobalConfig.setTrustAnyHost(true);
|
||||
requestBadSSL("httpclient4");
|
||||
requestBadSSL("httpclient5");
|
||||
requestBadSSL("okhttp");
|
||||
requestBadSSL("jdkClient");
|
||||
}
|
||||
|
||||
private void requestBadSSL(final String engineName) {
|
||||
final ClientEngine engine = HttpUtil.createClient(engineName);
|
||||
|
||||
final Request req = Request.of("https://expired.badssl.com/");
|
||||
final Response res = engine.send(req);
|
||||
Console.log(res.getStatus());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user