fix issue#3240

This commit is contained in:
Looly 2023-08-13 22:45:12 +08:00
parent ae4600d0c7
commit b02419c5f8
4 changed files with 80 additions and 33 deletions

View File

@ -18,7 +18,8 @@ import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
@ -31,10 +32,10 @@ import org.dromara.hutool.core.net.url.UrlBuilder;
import org.dromara.hutool.http.GlobalHeaders; import org.dromara.hutool.http.GlobalHeaders;
import org.dromara.hutool.http.HttpException; import org.dromara.hutool.http.HttpException;
import org.dromara.hutool.http.client.ClientConfig; import org.dromara.hutool.http.client.ClientConfig;
import org.dromara.hutool.http.client.engine.ClientEngine;
import org.dromara.hutool.http.client.Request; import org.dromara.hutool.http.client.Request;
import org.dromara.hutool.http.client.Response; import org.dromara.hutool.http.client.Response;
import org.dromara.hutool.http.client.body.HttpBody; import org.dromara.hutool.http.client.body.HttpBody;
import org.dromara.hutool.http.client.engine.ClientEngine;
import org.dromara.hutool.http.meta.HeaderName; import org.dromara.hutool.http.meta.HeaderName;
import org.dromara.hutool.http.proxy.HttpProxy; import org.dromara.hutool.http.proxy.HttpProxy;
import org.dromara.hutool.http.ssl.SSLInfo; import org.dromara.hutool.http.ssl.SSLInfo;
@ -77,7 +78,7 @@ public class HttpClient4Engine implements ClientEngine {
public Response send(final Request message) { public Response send(final Request message) {
initEngine(); initEngine();
final HttpEntityEnclosingRequestBase request = buildRequest(message); final HttpUriRequest request = buildRequest(message);
final CloseableHttpResponse response; final CloseableHttpResponse response;
try { try {
response = this.engine.execute(request); response = this.engine.execute(request);
@ -137,35 +138,33 @@ public class HttpClient4Engine implements ClientEngine {
* 构建请求体 * 构建请求体
* *
* @param message {@link Request} * @param message {@link Request}
* @return {@link HttpEntityEnclosingRequestBase} * @return {@link HttpUriRequest}
*/ */
private static HttpEntityEnclosingRequestBase buildRequest(final Request message) { private static HttpUriRequest buildRequest(final Request message) {
final UrlBuilder url = message.url(); final UrlBuilder url = message.url();
Assert.notNull(url, "Request URL must be not null!"); Assert.notNull(url, "Request URL must be not null!");
final URI uri = url.toURI(); final URI uri = url.toURI();
final HttpEntityEnclosingRequestBase request = new HttpEntityEnclosingRequestBase() { final RequestBuilder requestBuilder = RequestBuilder
@Override .create(message.method().name())
public String getMethod() { .setUri(uri);
return message.method().name();
}
};
request.setURI(uri);
// 填充自定义头 // 填充自定义头
request.setHeaders(toHeaderList(message.headers()).toArray(new Header[0])); message.headers().forEach((k, v1) -> v1.forEach((v2) -> requestBuilder.addHeader(k, v2)));
// 填充自定义消息体 // 填充自定义消息体
final HttpBody body = message.body(); final HttpBody body = message.body();
request.setEntity(new HttpClient4BodyEntity( if(null != body){
requestBuilder.setEntity(new HttpClient4BodyEntity(
// 用户自定义的内容类型 // 用户自定义的内容类型
message.header(HeaderName.CONTENT_TYPE), message.header(HeaderName.CONTENT_TYPE),
// 用户自定义编码 // 用户自定义编码
message.charset(), message.charset(),
message.isChunked(), message.isChunked(),
body)); body));
}
return request; return requestBuilder.build();
} }
/** /**

View File

@ -31,6 +31,7 @@ import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.message.BasicHeader; import org.apache.hc.core5.http.message.BasicHeader;
import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.net.url.UrlBuilder; import org.dromara.hutool.core.net.url.UrlBuilder;
import org.dromara.hutool.http.GlobalHeaders; import org.dromara.hutool.http.GlobalHeaders;
import org.dromara.hutool.http.HttpException; import org.dromara.hutool.http.HttpException;
@ -153,6 +154,7 @@ public class HttpClient5Engine implements ClientEngine {
// 填充自定义消息体 // 填充自定义消息体
final HttpBody body = message.body(); final HttpBody body = message.body();
if(null != body){
request.setEntity(new HttpClient5BodyEntity( request.setEntity(new HttpClient5BodyEntity(
// 用户自定义的内容类型 // 用户自定义的内容类型
message.header(HeaderName.CONTENT_TYPE), message.header(HeaderName.CONTENT_TYPE),
@ -160,6 +162,7 @@ public class HttpClient5Engine implements ClientEngine {
message.charset(), message.charset(),
message.isChunked(), message.isChunked(),
body)); body));
}
return request; return request;
} }

View File

@ -16,6 +16,7 @@ import okhttp3.OkHttpClient;
import okhttp3.internal.http.HttpMethod; import okhttp3.internal.http.HttpMethod;
import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IORuntimeException;
import org.dromara.hutool.http.client.ClientConfig; import org.dromara.hutool.http.client.ClientConfig;
import org.dromara.hutool.http.client.body.HttpBody;
import org.dromara.hutool.http.client.engine.ClientEngine; import org.dromara.hutool.http.client.engine.ClientEngine;
import org.dromara.hutool.http.client.Request; import org.dromara.hutool.http.client.Request;
import org.dromara.hutool.http.client.Response; import org.dromara.hutool.http.client.Response;
@ -112,7 +113,7 @@ public class OkHttpEngine implements ClientEngine {
} }
// 默认关闭自动跳转 // 默认关闭自动跳转
builder.followRedirects(false); builder.setFollowRedirects$okhttp(false);
this.client = builder.build(); this.client = builder.build();
} }
@ -129,8 +130,11 @@ public class OkHttpEngine implements ClientEngine {
// 填充方法 // 填充方法
final String method = message.method().name(); final String method = message.method().name();
if (HttpMethod.permitsRequestBody(method)) { final HttpBody body = message.body();
builder.method(method, new OkHttpRequestBody(message.body())); // if (HttpMethod.permitsRequestBody(method)) {
if (null != body) {
// 为了兼容支持rest请求在此不区分是否为GET等方法一律按照body是否有值填充
builder.method(method, new OkHttpRequestBody(body));
} else { } else {
builder.method(method, null); builder.method(method, null);
} }
@ -150,10 +154,10 @@ public class OkHttpEngine implements ClientEngine {
private static void setProxy(final OkHttpClient.Builder builder, final ClientConfig config) { private static void setProxy(final OkHttpClient.Builder builder, final ClientConfig config) {
final HttpProxy proxy = config.getProxy(); final HttpProxy proxy = config.getProxy();
if (null != proxy) { if (null != proxy) {
builder.proxy(proxy); builder.setProxy$okhttp(proxy);
final PasswordAuthentication auth = proxy.getAuth(); final PasswordAuthentication auth = proxy.getAuth();
if (null != auth) { if (null != auth) {
builder.proxyAuthenticator(new BasicProxyAuthenticator(auth)); builder.setProxyAuthenticator$okhttp(new BasicProxyAuthenticator(auth));
} }
} }
} }

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.http.client;
import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.http.client.engine.ClientEngine;
import org.dromara.hutool.http.client.engine.httpclient4.HttpClient4Engine;
import org.dromara.hutool.http.client.engine.okhttp.OkHttpEngine;
import org.dromara.hutool.http.meta.Method;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
public class Issue3240Test {
@Test
@Disabled
void okHttpTest() {
String url = "https://gh.yubue.cn/https://github.com/espressif/arduino-esp32/releases/download/2.0.11/package_esp32_dev_index.json";
final ClientEngine engine = new OkHttpEngine();
final Response send = engine.send(Request.of(url).method(Method.GET));
Console.log(send.body().getString());
}
@Test
@Disabled
void httpClient4Test() {
String url = "https://gh.yubue.cn/https://github.com/espressif/arduino-esp32/releases/download/2.0.11/package_esp32_dev_index.json";
final ClientEngine engine = new HttpClient4Engine();
final Response send = engine.send(Request.of(url).method(Method.GET));
Console.log(send.body().getString());
}
}