Commit c88f33c919666907020240a1dd3346810101e226

Authored by YunaiV
1 parent ba6cdabe

fix(infra): 修复文件名包含 + 号时预签名 URL 解码错误

yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/http/HttpUtils.java
... ... @@ -37,8 +37,10 @@ public class HttpUtils {
37 37 }
38 38  
39 39 /**
40   - * 解码 URL 参数
  40 + * 解码 URL 参数(query parameter)
  41 + * 注意:此方法会将 + 解码为空格,适用于 query parameter,不适用于 URL path
41 42 *
  43 + * @see #decodeUrlPath(String)
42 44 * @param value 参数
43 45 * @return 解码后的参数
44 46 */
... ... @@ -46,6 +48,20 @@ public class HttpUtils {
46 48 return URLDecoder.decode(value, StandardCharsets.UTF_8);
47 49 }
48 50  
  51 + /**
  52 + * 解码 URL 路径
  53 + * 与 {@link #decodeUtf8(String)} 不同,此方法不会将 + 解码为空格,保持 + 为字面字符
  54 + * 适用于 URL path 部分的解码
  55 + *
  56 + * @param path URL 路径
  57 + * @return 解码后的路径
  58 + */
  59 + public static String decodeUrlPath(String path) {
  60 + // 先将 + 替换为 %2B,避免被 URLDecoder 解码为空格
  61 + String encoded = path.replace("+", "%2B");
  62 + return URLDecoder.decode(encoded, StandardCharsets.UTF_8);
  63 + }
  64 +
49 65 @SuppressWarnings("unchecked")
50 66 public static String replaceUrlQuery(String url, String key, String value) {
51 67 UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());
... ...
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClient.java
... ... @@ -116,7 +116,7 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
116 116 public String presignGetUrl(String url, Integer expirationSeconds) {
117 117 // 1. 将 url 转换为 path
118 118 String path = StrUtil.removePrefix(url, config.getDomain() + "/");
119   - path = HttpUtils.decodeUtf8(HttpUtils.removeUrlQuery(path));
  119 + path = HttpUtils.decodeUrlPath(HttpUtils.removeUrlQuery(path));
120 120  
121 121 // 2.1 情况一:公开访问:无需签名
122 122 // 考虑到老版本的兼容,所以必须是 config.getEnablePublicAccess() 为 false 时,才进行签名
... ...