Cloudflare R2 在存储桶之间移动对象不适用于 S3 SDK

问题描述 投票:0回答:1

我尝试在两个资源之间移动我的对象。 首先,我执行 CopyRequest,然后执行 DeleteRequest。但是当我尝试移动对象时,出现以下错误:

Header 'x-amz-tagging-directive' with value 'COPY' not implemented

我尝试在创建 CopyObjectRequest 实例后删除标头,但没有名称相似的标头。另外,在创建 CopyObjectRequest 的新实例时,我没有看到任何配置。

S3客户端的配置和实例

var config = new AmazonS3Config
        {
            ServiceURL = SabiartConfig.SabiartS3Domain
        };
        
var credentials = new BasicAWSCredentials(SabiartConfig.SabiartS3Key, SabiartConfig.SabiartS3Secret);

_client = new AmazonS3Client(credentials, config);
await _fileService.MoveToBucket(fileIdString, SabiartConfig.SabiartS3TemporaryBucketName,
            SabiartConfig.SabiartS3PublicBucketName);

移动代码:

public async Task MoveToBucket(string fileIdString, string originBucket, string destinationBucket)
    {
        var request = new CopyObjectRequest
        {
            SourceBucket = originBucket,
            SourceKey = fileIdString,
            DestinationBucket = destinationBucket,
            DestinationKey = fileIdString
        };
        
        await _client.CopyObjectAsync(request);
        await DeleteAsync(fileIdString, originBucket);
    }

堆栈:

Amazon.S3.AmazonS3Exception: Header 'x-amz-tagging-directive' with value 'COPY' not implemented
 ---> Amazon.Runtime.Internal.HttpErrorResponseException: Exception of type 'Amazon.Runtime.Internal.HttpErrorResponseException' was thrown.
   at Amazon.Runtime.HttpWebRequestMessage.ProcessHttpResponseMessage(HttpResponseMessage responseMessage)
   at Amazon.Runtime.HttpWebRequestMessage.GetResponseAsync(CancellationToken cancellationToken)
   at Amazon.Runtime.Internal.HttpHandler`1.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RedirectHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.Unmarshaller.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.S3.Internal.AmazonS3ResponseHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
   --- End of inner exception stack trace ---
   at Amazon.Runtime.Internal.HttpErrorResponseExceptionHandler.HandleExceptionStream(IRequestContext requestContext, IWebResponseData httpErrorResponse, HttpErrorResponseException exception, Stream responseStream)
   at Amazon.Runtime.Internal.HttpErrorResponseExceptionHandler.HandleExceptionAsync(IExecutionContext executionContext, HttpErrorResponseException exception)
   at Amazon.Runtime.Internal.ExceptionHandler`1.HandleAsync(IExecutionContext executionContext, Exception exception)
   at Amazon.Runtime.Internal.ErrorHandler.ProcessExceptionAsync(IExecutionContext executionContext, Exception exception)
   at Amazon.Runtime.Internal.ErrorHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.Signer.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.EndpointDiscoveryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CredentialsRetriever.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.RetryHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.CallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.S3.Internal.AmazonS3ExceptionHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.ErrorCallbackHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Amazon.Runtime.Internal.MetricsHandler.InvokeAsync[T](IExecutionContext executionContext)
   at Sabiart.Gallery.Application.Services.FileServiceS3.MoveToBucket(String fileIdString, String originBucket, String destinationBucket) in E:\Projetos\sabiart\sabia.backend\src\Sabiart.Gallery.Application\Services\FileServiceS3.cs:line 116
c# .net amazon-s3 cloudflare cloudflare-r2
1个回答
0
投票

根据 CloudFlare 文档,仍然不支持

x-amz-tagging-directive
标头:

❌ x-amz-标记指令

CopyObject
API 本身并不严格需要
x-amz-tagging-directive
标头,因为 S3 内部默认为
COPY
;如果未发送标头,CloudFlare 可能会在幕后执行无操作,但 .NET SDK 不提供省略此标头的方法。它总是为此标头设置一个值,以确定是否需要复制对象的标签。

你可以从源代码中看到这一点:

if (copyObjectRequest.IsSetTagSet())
{
    request.Headers.Add(S3Constants.AmzHeaderTagging, AmazonS3Util.TagSetToQueryString(copyObjectRequest.TagSet));
    request.Headers.Add(S3Constants.AmzHeaderTaggingDirective, TaggingDirective.REPLACE.Value);
}
else
{
    request.Headers.Add(S3Constants.AmzHeaderTaggingDirective, TaggingDirective.COPY.Value);
}

不幸的是,在 CloudFlare 支持此标头之前,您需要手动

GetObject
PutObject
跨越对象。

© www.soinside.com 2019 - 2024. All rights reserved.