From 9a5fd52e9f3d0a6b3db1a864df175de69dc3027c Mon Sep 17 00:00:00 2001 From: Looly Date: Tue, 12 Dec 2023 23:05:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dgraalvm=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E6=9C=AA=E8=AF=BB=E5=8F=96Content-Length?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E5=AF=BC=E8=87=B4=E7=9A=84=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E8=BF=87=E9=95=BF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/net/multipart/MultipartFormData.java | 2 +- .../MultipartRequestInputStream.java | 10 ++++ .../hutool/http/server/HttpServerRequest.java | 26 ++++++++-- .../hutool/http/server/IssueI6Q30XTest.java | 49 +++++++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 hutool-http/src/test/java/org/dromara/hutool/http/server/IssueI6Q30XTest.java 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(); + } +}