From b10211d58b42aee3b6489800edd672d8fc9e144a Mon Sep 17 00:00:00 2001 From: CloudCauldron <110240653+CloudCauldron@users.noreply.github.com> Date: Thu, 4 Jun 2026 11:02:58 +0800 Subject: [PATCH] fix(115_open): refresh OSS STS token during multipart upload The OSS STS token returned by UploadGetToken expires in about 1 hour. multpartUpload created the OSS client once and never refreshed it, so a slow or large upload running past the token lifetime failed with SecurityTokenExpired and then InvalidAccessKeyId, aborting the transfer. Refresh the token after 45 minutes and rebuild the OSS client with the new credentials, reusing the same multipart upload session (imur) to continue uploading the remaining parts. Co-Authored-By: Claude --- drivers/115_open/upload.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/115_open/upload.go b/drivers/115_open/upload.go index d02640e2c..5ac0820c0 100644 --- a/drivers/115_open/upload.go +++ b/drivers/115_open/upload.go @@ -85,6 +85,30 @@ func (d *Open115) multpartUpload(ctx context.Context, stream model.FileStreamer, return err } + // The OSS STS token returned by UploadGetToken expires in about 1 hour. + // A slow or large upload can outlive it, causing SecurityTokenExpired / + // InvalidAccessKeyId. Refresh the token ahead of expiry and rebuild the OSS + // client with the new credentials, reusing the same multipart session (imur) + // to keep uploading the remaining parts. + tokenObtained := time.Now() + refreshOSSToken := func() error { + newToken, err := d.client.UploadGetToken(ctx) + if err != nil { + return err + } + newClient, err := netutil.NewOSSClient(newToken.Endpoint, newToken.AccessKeyId, newToken.AccessKeySecret, oss.SecurityToken(newToken.SecurityToken)) + if err != nil { + return err + } + newBucket, err := newClient.Bucket(initResp.Bucket) + if err != nil { + return err + } + bucket = newBucket + tokenObtained = time.Now() + return nil + } + fileSize := stream.GetSize() chunkSize := calPartSize(fileSize) ss, err := streamPkg.NewStreamSectionReader(stream, int(chunkSize), &up) @@ -100,6 +124,13 @@ func (d *Open115) multpartUpload(ctx context.Context, stream model.FileStreamer, return ctx.Err() } + // The token lives ~1 hour; refresh after 45 minutes to keep a safe margin. + if time.Since(tokenObtained) > 45*time.Minute { + if err := refreshOSSToken(); err != nil { + return err + } + } + partSize := chunkSize if i == partNum { partSize = fileSize - (i-1)*chunkSize