This commit is contained in:
2026-03-04 03:27:16 +08:00
parent f03dc678cf
commit 0d85a43082
8 changed files with 179 additions and 148 deletions

View File

@@ -198,9 +198,8 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
@Override
public String presignGetUrl(String url, Integer expirationSeconds) {
// 1. 将 url 转换为 path
String path = StrUtil.removePrefix(url, config.getDomain() + "/");
path = HttpUtils.removeUrlQuery(path);
// 1. 将 url 转换为 path(支持 CDN 域名和 OSS 原始域名)
String path = extractPathFromUrl(url);
String decodedPath = URLUtil.decode(path, StandardCharsets.UTF_8);
// 2. 公开访问:无需签名
@@ -272,6 +271,54 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
return StrUtil.format("https://{}", config.getEndpoint());
}
/**
* 从 URL 中提取 path支持 CDN 域名和 OSS 原始域名)
*
* @param url 完整的 URL
* @return 相对路径(不含查询参数)
*/
private String extractPathFromUrl(String url) {
if (StrUtil.isEmpty(url)) {
return url;
}
// 移除查询参数
String cleanUrl = HttpUtils.removeUrlQuery(url);
// 1. 尝试使用配置的 domain 提取 pathCDN 域名)
if (StrUtil.isNotEmpty(config.getDomain()) && cleanUrl.startsWith(config.getDomain() + "/")) {
return StrUtil.removePrefix(cleanUrl, config.getDomain() + "/");
}
// 2. 尝试从 OSS 原始域名提取 path阿里云格式
// 格式https://{bucket}.oss-{region}.aliyuncs.com/{path}
if (cleanUrl.contains(".aliyuncs.com/")) {
int pathStart = cleanUrl.indexOf(".aliyuncs.com/") + ".aliyuncs.com/".length();
if (pathStart < cleanUrl.length()) {
return cleanUrl.substring(pathStart);
}
}
// 3. 尝试从 buildDomain() 格式提取 path
String builtDomain = buildDomain();
if (cleanUrl.startsWith(builtDomain + "/")) {
return StrUtil.removePrefix(cleanUrl, builtDomain + "/");
}
// 4. 兜底:如果 URL 包含路径分隔符,尝试提取路径部分
int slashIndex = cleanUrl.indexOf("://");
if (slashIndex > 0) {
String afterProtocol = cleanUrl.substring(slashIndex + 3);
int pathIndex = afterProtocol.indexOf('/');
if (pathIndex > 0 && pathIndex < afterProtocol.length() - 1) {
return afterProtocol.substring(pathIndex + 1);
}
}
// 5. 最后兜底:直接返回原始 URL可能已经是 path
return cleanUrl;
}
/**
* 从 endpoint 中提取 region
*/