From 748c19f1085f3dd11d24e235ec54d3ab96993a00 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 20 Aug 2024 11:39:54 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20#3348=20=E3=80=90=E5=85=AC=E5=85=B1?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=91=E4=BF=AE=E5=A4=8D=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=AD=A3=E7=A1=AE=E6=96=87=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/util/http/HttpResponseProxy.java | 39 ++++++++++++++----- .../util/http/HttpResponseProxyTest.java | 26 +++++++++++++ 2 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 weixin-java-common/src/test/java/me/chanjar/weixin/common/util/http/HttpResponseProxyTest.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java index 3e0acb46f..11b120946 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java @@ -6,6 +6,12 @@ import okhttp3.Response; import org.apache.http.Header; import org.apache.http.client.methods.CloseableHttpResponse; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** *
  * 三种http框架的response代理类,方便提取公共方法
@@ -56,29 +62,42 @@ public class HttpResponseProxy {
       throw new WxErrorException("无法获取到文件名,Content-disposition为空");
     }
 
-    return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
+    return extractFileNameFromContentString(contentDispositionHeader[0].getValue());
   }
 
   private String getFileName(HttpResponse response) throws WxErrorException {
     String content = response.header("Content-disposition");
-    return this.extractFileNameFromContentString(content);
+    return extractFileNameFromContentString(content);
   }
 
   private String getFileName(Response response) throws WxErrorException {
     String content = response.header("Content-disposition");
-    return this.extractFileNameFromContentString(content);
+    return extractFileNameFromContentString(content);
   }
 
-  private String extractFileNameFromContentString(String content) throws WxErrorException {
-    if (content == null || content.length() == 0) {
+  public static String extractFileNameFromContentString(String content) throws WxErrorException {
+    if (content == null || content.isEmpty()) {
       throw new WxErrorException("无法获取到文件名,content为空");
     }
 
-    int startIndex = content.indexOf("filename=\"");
-    if (startIndex != -1) {
-      startIndex += "filename=\"".length();
-      int endIndex = content.indexOf('"', startIndex);
-      return content.substring(startIndex, endIndex);
+    // 查找filename*=utf-8''开头的部分
+    Pattern pattern = Pattern.compile("filename\\*=utf-8''(.*?)($|;|\\s|,)");
+    Matcher matcher = pattern.matcher(content);
+    if (matcher.find()) {
+      String encodedFileName = matcher.group(1);
+      // 解码URL编码的文件名
+      try {
+        return URLDecoder.decode(encodedFileName, StandardCharsets.UTF_8.name());
+      } catch (UnsupportedEncodingException e) {
+        throw new RuntimeException(e);
+      }
+    }
+
+    // 查找普通filename="..."部分
+    pattern = Pattern.compile("filename=\"(.*?)\"");
+    matcher = pattern.matcher(content);
+    if (matcher.find()) {
+      return new String(matcher.group(1).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
     }
 
     throw new WxErrorException("无法获取到文件名,header信息有问题");
diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/http/HttpResponseProxyTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/http/HttpResponseProxyTest.java
new file mode 100644
index 000000000..4d188b50b
--- /dev/null
+++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/http/HttpResponseProxyTest.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.common.util.http;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class HttpResponseProxyTest {
+
+  @Test
+  public void testExtractFileNameFromContentString() throws WxErrorException {
+    String content = "attachment; filename*=utf-8''%E6%B5%8B%E8%AF%95.xlsx; filename=\"��.xlsx\"";
+    String filename = HttpResponseProxy.extractFileNameFromContentString(content);
+    assertNotNull(filename);
+    assertEquals(filename, "测试.xlsx");
+  }
+
+  @Test
+  public void testExtractFileNameFromContentString_another() throws WxErrorException {
+    String content = "attachment; filename*=utf-8''%E8%90%A5%E4%B8%9A%E6%89%A7%E7%85%A7.jpg; filename=\"����.jpg\"";
+//    String content = "attachment; filename=\"����.jpg\"";
+    String filename = HttpResponseProxy.extractFileNameFromContentString(content);
+    assertNotNull(filename);
+    assertEquals(filename, "营业执照.jpg");
+  }
+}