diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/HttpDownloader.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/HttpDownloader.java
index 02bb69964..7df2cb714 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/client/HttpDownloader.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/HttpDownloader.java
@@ -81,6 +81,18 @@ public class HttpDownloader {
return this;
}
+ /**
+ * 设置请求头,多个请求头则多次调用
+ *
+ * @param name 请求头名
+ * @param value 请求头值
+ * @return this
+ */
+ public HttpDownloader header(final String name, final String value) {
+ this.request.header(name, value);
+ return this;
+ }
+
/**
* 设置配置
*
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java
index 14a222bd2..d6b17ecce 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/Request.java
@@ -46,7 +46,9 @@ import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
/**
- * 请求消息体,包括请求的URI、请求头、请求体等
+ * 请求消息
+ * 请求消息用于定义请求所需的信息,如请求URL、请求方法、请求头、请求体等
+ * 此对象为无状态对象,与具体引擎不相关,因此可以复用。
*
* @author looly
* @since 6.0.0
@@ -139,11 +141,6 @@ public class Request implements HeaderOperation {
* 是否是REST请求模式,REST模式运行GET请求附带body
*/
private boolean isRest;
- /**
- * 重定向计数器,内部使用
- * 单次请求时,重定向次数内部自增
- */
- private int redirectCount;
/**
* 默认构造
@@ -208,7 +205,8 @@ public class Request implements HeaderOperation {
}
/**
- * 设置重定向后的URL,用于处理相对路径
+ * 更新设置重定向后的URL,用于处理相对路径
+ * 注意此方法会修改对象本身
*
* @param location 重定向后的URL
* @return this
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/RequestContext.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/RequestContext.java
index 0f23433cb..85b0bc675 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/client/RequestContext.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/RequestContext.java
@@ -46,7 +46,7 @@ public class RequestContext {
}
/**
- * 设置请求
+ * 设置请求,在重新请求或重定向时,更新请求信息
*
* @param request 请求
* @return this
@@ -57,16 +57,18 @@ public class RequestContext {
}
/**
- * 是否允许重定向,如果允许,则重定向计数器+1
+ * 获取重定向计数器
*
- * @return 是否允许重定向
+ * @return 重定向计数器
*/
- public boolean canRedirect(){
- final int maxRedirects = request.maxRedirects();
- if(maxRedirects > 0 && redirectCount < maxRedirects){
- redirectCount++;
- return true;
- }
- return false;
+ public int getRedirectCount() {
+ return redirectCount;
+ }
+
+ /**
+ * 重定向计数器+1
+ */
+ public void incrementRedirectCount() {
+ this.redirectCount++;
}
}
diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java
index 49e33c872..6585f2cee 100644
--- a/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java
+++ b/hutool-http/src/main/java/org/dromara/hutool/http/client/engine/jdk/JdkClientEngine.java
@@ -177,8 +177,9 @@ public class JdkClientEngine extends AbstractClientEngine {
*/
private JdkHttpResponse sendRedirectIfPossible(final JdkHttpConnection conn, final RequestContext context) {
final Request message = context.getRequest();
+ final int maxRedirects = message.maxRedirects();
// 手动实现重定向
- if (message.maxRedirects() > 0) {
+ if (maxRedirects > 0 && context.getRedirectCount() < maxRedirects) {
final int code;
try {
code = conn.getCode();
@@ -189,8 +190,6 @@ public class JdkClientEngine extends AbstractClientEngine {
}
if (HttpStatus.isRedirected(code)) {
- message.locationTo(conn.header(HeaderName.LOCATION));
-
// https://www.rfc-editor.org/rfc/rfc7231#section-6.4.7
// https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections
// 307方法和消息主体都不发生变化。
@@ -198,10 +197,10 @@ public class JdkClientEngine extends AbstractClientEngine {
// 重定向默认使用GET
message.method(Method.GET);
}
-
- if (context.canRedirect()) {
- return doSend(context);
- }
+ message.locationTo(conn.header(HeaderName.LOCATION));
+ // 自增计数器
+ context.incrementRedirectCount();
+ return doSend(context);
}
}
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 df2db2843..db63e5877 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
@@ -157,7 +157,8 @@ public class OkHttpEngine extends AbstractClientEngine {
}
// 自定义重定向
- if(message.maxRedirects() > 0){
+ final int maxRedirects = message.maxRedirects();
+ if(maxRedirects > 0 && context.getRedirectCount() < maxRedirects){
final int code = response.code();
if (HttpStatus.isRedirected(code)) {
message.locationTo(response.header(HeaderName.LOCATION.getValue()));
@@ -169,10 +170,9 @@ public class OkHttpEngine extends AbstractClientEngine {
// 重定向默认使用GET
message.method(Method.GET);
}
-
- if (context.canRedirect()) {
- return doSend(context);
- }
+ // 自增计数器
+ context.incrementRedirectCount();
+ return doSend(context);
}
return new OkHttpResponse(response, message);
diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/client/DownloadTest.java b/hutool-http/src/test/java/org/dromara/hutool/http/client/DownloadTest.java
index af0f5fc3e..3f49ab739 100644
--- a/hutool-http/src/test/java/org/dromara/hutool/http/client/DownloadTest.java
+++ b/hutool-http/src/test/java/org/dromara/hutool/http/client/DownloadTest.java
@@ -19,6 +19,7 @@ package org.dromara.hutool.http.client;
import org.dromara.hutool.core.io.StreamProgress;
import org.dromara.hutool.core.io.file.FileUtil;
import org.dromara.hutool.core.lang.Console;
+import org.dromara.hutool.core.map.MapUtil;
import org.dromara.hutool.http.HttpGlobalConfig;
import org.dromara.hutool.http.client.engine.ClientEngineFactory;
import org.junit.jupiter.api.Assertions;
@@ -50,6 +51,13 @@ public class DownloadTest {
Console.log("Download size: " + size);
}
+ @Test
+ void downloadWithHeaderTest() {
+ HttpDownloader.of("https://hutool.cn/")
+ .header(MapUtil.of("Authorization", "token"))
+ .downloadFile(FileUtil.file("d:/test/"));
+ }
+
@Test
@Disabled
public void downloadTest() {