From b02419c5f8e4447c2690c45770954731768e5743 Mon Sep 17 00:00:00 2001 From: Looly Date: Sun, 13 Aug 2023 22:45:12 +0800 Subject: [PATCH] fix issue#3240 --- .../engine/httpclient4/HttpClient4Engine.java | 41 +++++++++---------- .../engine/httpclient5/HttpClient5Engine.java | 17 ++++---- .../client/engine/okhttp/OkHttpEngine.java | 14 ++++--- .../hutool/http/client/Issue3240Test.java | 41 +++++++++++++++++++ 4 files changed, 80 insertions(+), 33 deletions(-) create mode 100755 hutool-http/src/test/java/org/dromara/hutool/http/client/Issue3240Test.java diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java index 7bb75b89a..9c3b66a2c 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient4/HttpClient4Engine.java @@ -18,7 +18,8 @@ import org.apache.http.auth.AuthScope; 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.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.impl.client.BasicCredentialsProvider; 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.HttpException; 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.Response; 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.proxy.HttpProxy; import org.dromara.hutool.http.ssl.SSLInfo; @@ -77,7 +78,7 @@ public class HttpClient4Engine implements ClientEngine { public Response send(final Request message) { initEngine(); - final HttpEntityEnclosingRequestBase request = buildRequest(message); + final HttpUriRequest request = buildRequest(message); final CloseableHttpResponse response; try { response = this.engine.execute(request); @@ -137,35 +138,33 @@ public class HttpClient4Engine implements ClientEngine { * 构建请求体 * * @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(); Assert.notNull(url, "Request URL must be not null!"); final URI uri = url.toURI(); - final HttpEntityEnclosingRequestBase request = new HttpEntityEnclosingRequestBase() { - @Override - public String getMethod() { - return message.method().name(); - } - }; - request.setURI(uri); + final RequestBuilder requestBuilder = RequestBuilder + .create(message.method().name()) + .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(); - request.setEntity(new HttpClient4BodyEntity( - // 用户自定义的内容类型 - message.header(HeaderName.CONTENT_TYPE), - // 用户自定义编码 - message.charset(), - message.isChunked(), - body)); + if(null != body){ + requestBuilder.setEntity(new HttpClient4BodyEntity( + // 用户自定义的内容类型 + message.header(HeaderName.CONTENT_TYPE), + // 用户自定义编码 + message.charset(), + message.isChunked(), + body)); + } - return request; + return requestBuilder.build(); } /** diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java index c0aad63f1..9edf71ddc 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/httpclient5/HttpClient5Engine.java @@ -31,6 +31,7 @@ import org.apache.hc.core5.http.HttpHost; import org.apache.hc.core5.http.message.BasicHeader; import org.dromara.hutool.core.io.IoUtil; 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.http.GlobalHeaders; import org.dromara.hutool.http.HttpException; @@ -153,13 +154,15 @@ public class HttpClient5Engine implements ClientEngine { // 填充自定义消息体 final HttpBody body = message.body(); - request.setEntity(new HttpClient5BodyEntity( - // 用户自定义的内容类型 - message.header(HeaderName.CONTENT_TYPE), - // 用户自定义编码 - message.charset(), - message.isChunked(), - body)); + if(null != body){ + request.setEntity(new HttpClient5BodyEntity( + // 用户自定义的内容类型 + message.header(HeaderName.CONTENT_TYPE), + // 用户自定义编码 + message.charset(), + message.isChunked(), + body)); + } return request; } diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java index 508e04ae5..ef83ce032 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/okhttp/OkHttpEngine.java @@ -16,6 +16,7 @@ import okhttp3.OkHttpClient; import okhttp3.internal.http.HttpMethod; import org.dromara.hutool.core.io.IORuntimeException; 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.Request; 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(); } @@ -129,8 +130,11 @@ public class OkHttpEngine implements ClientEngine { // 填充方法 final String method = message.method().name(); - if (HttpMethod.permitsRequestBody(method)) { - builder.method(method, new OkHttpRequestBody(message.body())); + final HttpBody body = message.body(); + // if (HttpMethod.permitsRequestBody(method)) { + if (null != body) { + // 为了兼容支持rest请求,在此不区分是否为GET等方法,一律按照body是否有值填充 + builder.method(method, new OkHttpRequestBody(body)); } else { builder.method(method, null); } @@ -150,10 +154,10 @@ public class OkHttpEngine implements ClientEngine { private static void setProxy(final OkHttpClient.Builder builder, final ClientConfig config) { final HttpProxy proxy = config.getProxy(); if (null != proxy) { - builder.proxy(proxy); + builder.setProxy$okhttp(proxy); final PasswordAuthentication auth = proxy.getAuth(); if (null != auth) { - builder.proxyAuthenticator(new BasicProxyAuthenticator(auth)); + builder.setProxyAuthenticator$okhttp(new BasicProxyAuthenticator(auth)); } } } diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/client/Issue3240Test.java b/hutool-http/src/test/java/org/dromara/hutool/http/client/Issue3240Test.java new file mode 100755 index 000000000..9b54b5701 --- /dev/null +++ b/hutool-http/src/test/java/org/dromara/hutool/http/client/Issue3240Test.java @@ -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()); + } +}