mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-06 16:07:01 +08:00
fix(storage): refresh 115 upload token when SecurityTokenExpired (#6296)
This commit is contained in:
@@ -751,6 +751,25 @@ class U115Pan(StorageBase, metaclass=WeakSingleton):
|
|||||||
object_name, params={"encoding-type": "url", "sequential": ""}
|
object_name, params={"encoding-type": "url", "sequential": ""}
|
||||||
).upload_id
|
).upload_id
|
||||||
parts = []
|
parts = []
|
||||||
|
|
||||||
|
def refresh_upload_bucket() -> oss2.Bucket:
|
||||||
|
"""
|
||||||
|
上传凭证过期时重新获取 115 上传凭证并重建 OSS Bucket。
|
||||||
|
"""
|
||||||
|
token_resp = self._request_api("GET", "/open/upload/get_token", "data")
|
||||||
|
if not token_resp:
|
||||||
|
raise Exception("【115】重新获取上传凭证失败")
|
||||||
|
logger.info("【115】已重新获取上传凭证,继续上传")
|
||||||
|
return oss2.Bucket(
|
||||||
|
oss2.StsAuth(
|
||||||
|
access_key_id=token_resp.get("AccessKeyId"),
|
||||||
|
access_key_secret=token_resp.get("AccessKeySecret"),
|
||||||
|
security_token=token_resp.get("SecurityToken"),
|
||||||
|
),
|
||||||
|
token_resp.get("endpoint"),
|
||||||
|
bucket_name,
|
||||||
|
)
|
||||||
|
|
||||||
# 逐个上传分片
|
# 逐个上传分片
|
||||||
with open(local_path, "rb") as fileobj:
|
with open(local_path, "rb") as fileobj:
|
||||||
part_number = 1
|
part_number = 1
|
||||||
@@ -764,12 +783,28 @@ class U115Pan(StorageBase, metaclass=WeakSingleton):
|
|||||||
logger.info(
|
logger.info(
|
||||||
f"【115】开始上传 {target_name} 分片 {part_number}: {offset} -> {offset + num_to_upload}"
|
f"【115】开始上传 {target_name} 分片 {part_number}: {offset} -> {offset + num_to_upload}"
|
||||||
)
|
)
|
||||||
result = bucket.upload_part(
|
retries = 0
|
||||||
object_name,
|
while True:
|
||||||
upload_id,
|
try:
|
||||||
part_number,
|
# 失败重试时确保从分片起始位置重新读取
|
||||||
data=SizedFileAdapter(fileobj, num_to_upload),
|
fileobj.seek(offset)
|
||||||
)
|
result = bucket.upload_part(
|
||||||
|
object_name,
|
||||||
|
upload_id,
|
||||||
|
part_number,
|
||||||
|
data=SizedFileAdapter(fileobj, num_to_upload),
|
||||||
|
)
|
||||||
|
break
|
||||||
|
except oss2.exceptions.OssError as e:
|
||||||
|
# 上传凭证过期时重新获取凭证并重试当前分片(最多重试 5 次)
|
||||||
|
if e.status == 403 and e.code == "SecurityTokenExpired" and retries < 5:
|
||||||
|
retries += 1
|
||||||
|
logger.warn(
|
||||||
|
f"【115】上传凭证已过期,重新获取凭证后重试 {target_name} 分片 {part_number}(第 {retries} 次)"
|
||||||
|
)
|
||||||
|
bucket = refresh_upload_bucket()
|
||||||
|
continue
|
||||||
|
raise
|
||||||
parts.append(PartInfo(part_number, result.etag))
|
parts.append(PartInfo(part_number, result.etag))
|
||||||
logger.info(f"【115】{target_name} 分片 {part_number} 上传完成")
|
logger.info(f"【115】{target_name} 分片 {part_number} 上传完成")
|
||||||
offset += num_to_upload
|
offset += num_to_upload
|
||||||
@@ -788,9 +823,23 @@ class U115Pan(StorageBase, metaclass=WeakSingleton):
|
|||||||
"x-oss-forbid-overwrite": "false",
|
"x-oss-forbid-overwrite": "false",
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
result = bucket.complete_multipart_upload(
|
retries = 0
|
||||||
object_name, upload_id, parts, headers=headers
|
while True:
|
||||||
)
|
try:
|
||||||
|
result = bucket.complete_multipart_upload(
|
||||||
|
object_name, upload_id, parts, headers=headers
|
||||||
|
)
|
||||||
|
break
|
||||||
|
except oss2.exceptions.OssError as e:
|
||||||
|
# 上传凭证过期时重新获取凭证后重试完成上传(最多重试 5 次)
|
||||||
|
if e.status == 403 and e.code == "SecurityTokenExpired" and retries < 5:
|
||||||
|
retries += 1
|
||||||
|
logger.warn(
|
||||||
|
f"【115】上传凭证已过期,重新获取凭证后重试完成上传(第 {retries} 次)"
|
||||||
|
)
|
||||||
|
bucket = refresh_upload_bucket()
|
||||||
|
continue
|
||||||
|
raise
|
||||||
if result.status != 200:
|
if result.status != 200:
|
||||||
logger.warn(f"【115】{target_name} 上传失败,错误码: {result.status}")
|
logger.warn(f"【115】{target_name} 上传失败,错误码: {result.status}")
|
||||||
return None
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user