mirror of
https://gitee.com/dromara/hutool.git
synced 2026-02-09 09:16:26 +08:00
add proxy support
This commit is contained in:
@@ -18,6 +18,7 @@ package cn.hutool.v7.http;
|
||||
|
||||
import cn.hutool.v7.core.util.RandomUtil;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
@@ -28,6 +29,7 @@ import java.net.HttpURLConnection;
|
||||
* @since 4.6.2
|
||||
*/
|
||||
public class HttpGlobalConfig implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
@@ -168,7 +170,7 @@ public class HttpGlobalConfig implements Serializable {
|
||||
|
||||
/**
|
||||
* 是否信任所有Host<br>
|
||||
* 见:https://github.com/chinabugotech/hutool/issues/2042<br>
|
||||
* 见:<a href="https://github.com/chinabugotech/hutool/issues/2042">issue#2042</a><br>
|
||||
*
|
||||
* @param customTrustAnyHost 如果设置为{@code false},则按照JDK默认验证机制,验证目标服务器的证书host和请求host是否一致,{@code true}表示不验证。
|
||||
* @since 5.8.27
|
||||
|
||||
@@ -19,7 +19,6 @@ package cn.hutool.v7.http;
|
||||
import cn.hutool.v7.core.collection.CollUtil;
|
||||
import cn.hutool.v7.core.map.CaseInsensitiveMap;
|
||||
import cn.hutool.v7.core.map.MapUtil;
|
||||
import cn.hutool.v7.core.net.url.UrlQueryUtil;
|
||||
import cn.hutool.v7.core.text.StrUtil;
|
||||
import cn.hutool.v7.http.client.ClientConfig;
|
||||
import cn.hutool.v7.http.client.Request;
|
||||
@@ -208,75 +207,6 @@ public class HttpUtil {
|
||||
return ClientEngineFactory.getEngine().send(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将表单数据加到URL中(用于GET表单提交)
|
||||
* 表单的键值对会被url编码,但是url中原参数不会被编码
|
||||
* 且对form参数进行 FormUrlEncoded ,x-www-form-urlencoded模式,此模式下空格会编码为'+'
|
||||
*
|
||||
* @param url URL
|
||||
* @param form 表单数据
|
||||
* @param charset 编码 null表示不encode键值对
|
||||
* @return 合成后的URL
|
||||
*/
|
||||
public static String urlWithFormUrlEncoded(final String url, final Map<String, Object> form, final Charset charset) {
|
||||
return urlWithForm(url, form, charset, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将表单数据加到URL中(用于GET表单提交)<br>
|
||||
* 表单的键值对会被url编码,但是url中原参数不会被编码
|
||||
*
|
||||
* @param url URL
|
||||
* @param form 表单数据
|
||||
* @param charset 编码
|
||||
* @param isEncodeParams 是否对键和值做转义处理
|
||||
* @return 合成后的URL
|
||||
*/
|
||||
public static String urlWithForm(final String url, final Map<String, Object> form, final Charset charset, final boolean isEncodeParams) {
|
||||
return urlWithForm(url, UrlQueryUtil.toQuery(form, null), charset, isEncodeParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将表单数据字符串加到URL中(用于GET表单提交)
|
||||
*
|
||||
* @param url URL
|
||||
* @param queryString 表单数据字符串
|
||||
* @param charset 编码
|
||||
* @param isEncode 是否对键和值做转义处理
|
||||
* @return 拼接后的字符串
|
||||
*/
|
||||
public static String urlWithForm(final String url, final String queryString, final Charset charset, final boolean isEncode) {
|
||||
if (StrUtil.isBlank(queryString)) {
|
||||
// 无额外参数
|
||||
if (StrUtil.contains(url, '?')) {
|
||||
// url中包含参数
|
||||
return isEncode ? UrlQueryUtil.encodeQuery(url, charset) : url;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
// 始终有参数
|
||||
final StringBuilder urlBuilder = new StringBuilder(url.length() + queryString.length() + 16);
|
||||
final int qmIndex = url.indexOf('?');
|
||||
if (qmIndex > 0) {
|
||||
// 原URL带参数,则对这部分参数单独编码(如果选项为进行编码)
|
||||
urlBuilder.append(isEncode ? UrlQueryUtil.encodeQuery(url, charset) : url);
|
||||
if (!StrUtil.endWith(url, '&')) {
|
||||
// 已经带参数的情况下追加参数
|
||||
urlBuilder.append('&');
|
||||
}
|
||||
} else {
|
||||
// 原url无参数,则不做编码
|
||||
urlBuilder.append(url);
|
||||
if (qmIndex < 0) {
|
||||
// 无 '?' 追加之
|
||||
urlBuilder.append('?');
|
||||
}
|
||||
}
|
||||
urlBuilder.append(isEncode ? UrlQueryUtil.encodeQuery(queryString, charset) : queryString);
|
||||
return urlBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建客户端引擎
|
||||
*
|
||||
|
||||
@@ -28,7 +28,6 @@ import cn.hutool.v7.http.ssl.SSLInfo;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
|
||||
@@ -30,19 +30,9 @@ import java.net.PasswordAuthentication;
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
* @param auth 账号密码
|
||||
*/
|
||||
public class BasicProxyAuthenticator implements Authenticator {
|
||||
|
||||
private final PasswordAuthentication auth;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param passwordAuthentication 账号密码对
|
||||
*/
|
||||
public BasicProxyAuthenticator(final PasswordAuthentication passwordAuthentication) {
|
||||
auth = passwordAuthentication;
|
||||
}
|
||||
public record BasicProxyAuthenticator(PasswordAuthentication auth) implements Authenticator {
|
||||
|
||||
@Override
|
||||
public Request authenticate(final Route route, final Response response) {
|
||||
|
||||
@@ -31,26 +31,17 @@ import java.util.List;
|
||||
*
|
||||
* @author Looly
|
||||
* @since 6.0.0
|
||||
* @param cookieStore Cookie存储器,用于自定义Cookie存储实现
|
||||
*/
|
||||
public class CookieJarImpl implements CookieJar {
|
||||
|
||||
private final CookieStoreSpi cookieStore;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param cookieStore Cookie存储器,用于自定义Cookie存储实现
|
||||
*/
|
||||
public CookieJarImpl(final CookieStoreSpi cookieStore) {
|
||||
this.cookieStore = cookieStore;
|
||||
}
|
||||
public record CookieJarImpl(CookieStoreSpi cookieStore) implements CookieJar {
|
||||
|
||||
/**
|
||||
* 获取Cookie存储器
|
||||
*
|
||||
* @return Cookie存储器
|
||||
*/
|
||||
public CookieStoreSpi getCookieStore() {
|
||||
@Override
|
||||
public CookieStoreSpi cookieStore() {
|
||||
return this.cookieStore;
|
||||
}
|
||||
|
||||
@@ -59,14 +50,14 @@ public class CookieJarImpl implements CookieJar {
|
||||
final List<CookieSpi> cookieSpis = this.cookieStore.get(httpUrl.uri());
|
||||
final List<Cookie> cookies = new ArrayList<>(cookieSpis.size());
|
||||
for (final CookieSpi cookieSpi : cookieSpis) {
|
||||
cookies.add(((OkCookie)cookieSpi).getRaw());
|
||||
cookies.add(((OkCookie) cookieSpi).getRaw());
|
||||
}
|
||||
return cookies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveFromResponse(final HttpUrl httpUrl, final List<Cookie> list) {
|
||||
if(CollUtil.isEmpty(list)){
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -131,30 +130,6 @@ public class HttpUtilTest {
|
||||
Console.log(body);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void urlWithFormTest() {
|
||||
final Map<String, Object> param = new LinkedHashMap<>();
|
||||
param.put("AccessKeyId", "123");
|
||||
param.put("Action", "DescribeDomainRecords");
|
||||
param.put("Format", "date");
|
||||
param.put("DomainName", "lesper.cn"); // 域名地址
|
||||
param.put("SignatureMethod", "POST");
|
||||
param.put("SignatureNonce", "123");
|
||||
param.put("SignatureVersion", "4.3.1");
|
||||
param.put("Timestamp", 123432453);
|
||||
param.put("Version", "1.0");
|
||||
|
||||
String urlWithForm = HttpUtil.urlWithForm("http://api.hutool.cn/login?type=aaa", param, CharsetUtil.UTF_8, false);
|
||||
Assertions.assertEquals(
|
||||
"http://api.hutool.cn/login?type=aaa&AccessKeyId=123&Action=DescribeDomainRecords&Format=date&DomainName=lesper.cn&SignatureMethod=POST&SignatureNonce=123&SignatureVersion=4.3.1&Timestamp=123432453&Version=1.0",
|
||||
urlWithForm);
|
||||
|
||||
urlWithForm = HttpUtil.urlWithForm("http://api.hutool.cn/login?type=aaa", param, CharsetUtil.UTF_8, false);
|
||||
Assertions.assertEquals(
|
||||
"http://api.hutool.cn/login?type=aaa&AccessKeyId=123&Action=DescribeDomainRecords&Format=date&DomainName=lesper.cn&SignatureMethod=POST&SignatureNonce=123&SignatureVersion=4.3.1&Timestamp=123432453&Version=1.0",
|
||||
urlWithForm);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void getWeixinTest(){
|
||||
|
||||
@@ -18,6 +18,7 @@ package cn.hutool.v7.http;
|
||||
|
||||
import cn.hutool.v7.core.net.url.UrlQuery;
|
||||
import cn.hutool.v7.core.net.url.UrlQueryUtil;
|
||||
import cn.hutool.v7.core.net.url.UrlUtil;
|
||||
import cn.hutool.v7.core.util.CharsetUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -35,7 +36,7 @@ public class Issue3536Test {
|
||||
paramMap.put("redirect_uri", "https://api.hutool.cn/v1/test");
|
||||
paramMap.put("scope", "a,b,c你");
|
||||
|
||||
final String s = HttpUtil.urlWithFormUrlEncoded(url, paramMap, CharsetUtil.UTF_8);
|
||||
final String s = UrlUtil.urlWithFormUrlEncoded(url, paramMap, CharsetUtil.UTF_8);
|
||||
assertEquals("https://hutool.cn/test?scope=a,b,c%E4%BD%A0&redirect_uri=https://api.hutool.cn/v1/test", s);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package cn.hutool.v7.http;
|
||||
|
||||
import cn.hutool.v7.core.collection.ListUtil;
|
||||
import cn.hutool.v7.core.net.url.UrlQuery;
|
||||
import cn.hutool.v7.core.net.url.UrlUtil;
|
||||
import cn.hutool.v7.core.util.CharsetUtil;
|
||||
import cn.hutool.v7.json.JSONObject;
|
||||
import cn.hutool.v7.json.JSONUtil;
|
||||
@@ -39,12 +40,12 @@ public class IssueIAFKWPTest {
|
||||
|
||||
// form-url-encoded模式下所有字符转义
|
||||
String build = UrlQuery.of(params, UrlQuery.EncodeMode.FORM_URL_ENCODED).build(CharsetUtil.UTF_8);
|
||||
String s = HttpUtil.urlWithForm("https://hutool.cn", build, CharsetUtil.UTF_8, false);
|
||||
String s = UrlUtil.urlWithForm("https://hutool.cn", build, CharsetUtil.UTF_8, false);
|
||||
Assertions.assertEquals("https://hutool.cn?query=%7B%22fields%22%3A%5B%221%22%2C%222%22%2C%22good%22%5D%7D", s);
|
||||
|
||||
// 标准模式下只转义特定字符
|
||||
build = UrlQuery.of(params, UrlQuery.EncodeMode.NORMAL).build(CharsetUtil.UTF_8);
|
||||
s = HttpUtil.urlWithForm("https://hutool.cn", build, CharsetUtil.UTF_8, false);
|
||||
s = UrlUtil.urlWithForm("https://hutool.cn", build, CharsetUtil.UTF_8, false);
|
||||
Assertions.assertEquals("https://hutool.cn?query=%7B%22fields%22:%5B%221%22,%222%22,%22good%22%5D%7D", s);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user