diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartFormData.java b/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartFormData.java index 39800098a..55747b2e0 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartFormData.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartFormData.java @@ -81,7 +81,7 @@ public class MultipartFormData { if (header.isFile == true) { // 文件类型的表单项 final String fileName = header.fileName; - if (fileName.length() > 0 && header.contentType.contains("application/x-macbinary")) { + if (!fileName.isEmpty() && header.contentType.contains("application/x-macbinary")) { input.skipBytes(128); } final UploadFile newFile = new UploadFile(header, setting); diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartRequestInputStream.java b/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartRequestInputStream.java index 45e922573..c6817a7c8 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartRequestInputStream.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/net/multipart/MultipartRequestInputStream.java @@ -29,6 +29,11 @@ import java.nio.charset.Charset; */ public class MultipartRequestInputStream extends BufferedInputStream { + /** + * 构造 + * + * @param in {@link InputStream} + */ public MultipartRequestInputStream(final InputStream in) { super(in); } @@ -101,6 +106,11 @@ public class MultipartRequestInputStream extends BufferedInputStream { protected UploadFileHeader lastHeader; + /** + * 获取最后的头信息 + * + * @return 头信息 + */ public UploadFileHeader getLastHeader() { return lastHeader; } diff --git a/hutool-http/src/main/java/org/dromara/hutool/http/server/HttpServerRequest.java b/hutool-http/src/main/java/org/dromara/hutool/http/server/HttpServerRequest.java index cbdc0d558..01dfe3d6a 100644 --- a/hutool-http/src/main/java/org/dromara/hutool/http/server/HttpServerRequest.java +++ b/hutool-http/src/main/java/org/dromara/hutool/http/server/HttpServerRequest.java @@ -12,8 +12,12 @@ package org.dromara.hutool.http.server; +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.io.IORuntimeException; import org.dromara.hutool.core.io.IoUtil; +import org.dromara.hutool.core.io.stream.LimitedInputStream; import org.dromara.hutool.core.map.CaseInsensitiveMap; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.core.map.multi.ListValueMap; @@ -22,7 +26,6 @@ import org.dromara.hutool.core.net.multipart.MultipartFormData; import org.dromara.hutool.core.net.multipart.UploadSetting; import org.dromara.hutool.core.net.url.UrlQueryUtil; import org.dromara.hutool.core.text.StrUtil; -import org.dromara.hutool.core.array.ArrayUtil; import org.dromara.hutool.core.util.CharsetUtil; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.http.meta.ContentTypeUtil; @@ -30,8 +33,6 @@ import org.dromara.hutool.http.meta.HeaderName; import org.dromara.hutool.http.meta.Method; import org.dromara.hutool.http.useragent.UserAgent; import org.dromara.hutool.http.useragent.UserAgentUtil; -import com.sun.net.httpserver.Headers; -import com.sun.net.httpserver.HttpExchange; import java.io.IOException; import java.io.InputStream; @@ -305,7 +306,24 @@ public class HttpServerRequest extends HttpServerBase { * @return 流 */ public InputStream getBodyStream() { - return this.httpExchange.getRequestBody(); + InputStream bodyStream = this.httpExchange.getRequestBody(); + + //issue#I6Q30X,读取body长度,避免读取结束后无法正常结束问题 + final String contentLengthStr = getHeader(HeaderName.CONTENT_LENGTH); + long contentLength = 0; + if(StrUtil.isNotBlank(contentLengthStr)){ + try{ + contentLength = Long.parseLong(contentLengthStr); + } catch (final NumberFormatException ignore){ + // ignore + } + } + + if(contentLength > 0){ + bodyStream = new LimitedInputStream(bodyStream, contentLength); + } + + return bodyStream; } /** diff --git a/hutool-http/src/test/java/org/dromara/hutool/http/server/IssueI6Q30XTest.java b/hutool-http/src/test/java/org/dromara/hutool/http/server/IssueI6Q30XTest.java new file mode 100644 index 000000000..64f4d805e --- /dev/null +++ b/hutool-http/src/test/java/org/dromara/hutool/http/server/IssueI6Q30XTest.java @@ -0,0 +1,49 @@ +/* + * 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: + * https://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.server; + +import org.dromara.hutool.core.date.DateUtil; +import org.dromara.hutool.core.date.StopWatch; +import org.dromara.hutool.core.lang.Console; +import org.dromara.hutool.core.net.multipart.MultipartFormData; +import org.dromara.hutool.http.HttpUtil; + +import java.util.concurrent.TimeUnit; + +/** + * 测试上传超时情况
+ * https://gitee.com/dromara/hutool/issues/I6Q30X
+ * + * post http://localhost:8888/file + * form-data: file: file-data + */ +public class IssueI6Q30XTest { + public static void main(String[] args) { + final SimpleServer server = HttpUtil.createServer(8888); + server.addAction("/file", (request, response) -> { + Console.log(request.getHeaders().entrySet()); + + final StopWatch stopWatch = DateUtil.createStopWatch(); + stopWatch.start(); + // graalvm编译后可能变慢 + final MultipartFormData multipart = request.getMultipart(); + stopWatch.stop(); + Console.log(stopWatch.prettyPrint(TimeUnit.MILLISECONDS)); + + multipart.getFile("file").write("d:/test/uploadFile"); + + response.write("OK"); + }); + server.start(); + } +}