当前位置: 首页 > 知识库问答 >
问题:

使用预签名URL将文件上载到AWS S3的代码有什么问题?

阚吕恭
2023-03-14

我想使用预先签名的URL将一个文件从iOS应用程序上传到AWS S3 bucket。URL是正确的,因为它在命令行上与curl一起工作。

curl -v -k --upload-file FILENAME "https://MYBUCKET.amazonaws.com:443/KEYNAME?Signature=...&Expires=1391691489&AWSAccessKeyId=..."

使用以下Objective-C代码...

- (void)upload:(NSString *)url fileData:(NSData *)fileData
{
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:url]];
    [request setHTTPMethod:@"PUT"];
    [request setHTTPBody:fileData];
    [request setValue:[NSString stringWithFormat:@"%d", [fileData length]] forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"audio/mpeg" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"public-read" forHTTPHeaderField:@"x-amz-acl"];
    [request setValue:@"iPhone-OS/6.0 fr_FR NE" forHTTPHeaderField:@"User-Agent"];

    _connection = [NSURLConnection connectionWithRequest:request delegate:self];
    [_connection start];
}

…我得到了这个错误:

Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x9c49560 {NSErrorFailingURLStringKey=https://MYBUCKET.s3.amazonaws.com:443/KEYNAME?Signature=...&Expires=1391703958&AWSAccessKeyId=..., NSErrorFailingURLKey=https://MYBUCKET.amazonaws.com:443/KEYNAME?Signature=...&Expires=1391703958&AWSAccessKeyId=..., NSLocalizedDescription=The request timed out., NSUnderlyingError=0x9c48c80 "The request timed out."}

我用WireShark看有没有流量,流量很多。

我不知道我的代码有什么问题。似乎文件传输没有正确终止。

共有1个答案

公羊玉泽
2023-03-14

我自己解决了这个问题。内容类型标题是罪魁祸首。在完全绝望的情况下,我用一个非常小的文本文件测试了我的代码,得到403作为来自S3的HTTP状态代码。没有超时。这样的进步。我还收到了一条信息丰富的错误消息:

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><StringToSignBytes>...</StringToSignBytes><RequestId>...</RequestId><HostId>...</HostId><SignatureProvided>...</SignatureProvided>
    <StringToSign>PUT

    text/plain
    1391784394
    KEYNAME</StringToSign>
    <AWSAccessKeyId>...</AWSAccessKeyId>
</Error>

显然,如果内容类型字符串(在本例中为text/plain)作为来自客户端的HTTP头提供,则它应该在字符串中签名。不要问我为什么这会导致大容量(5.5MB?)文件夹。我希望这能为其他人节省几个小时的生命时间。

最简单的修复方法是删除线路

[request setValue:@"..." forHTTPHeaderField:@"Content-Type"];

如果您在创建预签名URL时知道内容类型,那么您当然可以将字符串添加到要签名的字符串中。

 类似资料:
  • 我正在尝试使用预先签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL https://com-example-mysite.s3-us-east-1.amazonaws.com/userFolder/ImageName?X-Amz安全令牌=xxfoox///xxbarxx= 不幸的是,当我将其传递给Refught2时,它会修改试图将其转换为URL的字符串。我设置了,它解决

  • 这里是我的node.js预签名URL的生成 那么我在URL生成或卷曲方面的问题在哪里呢?谢谢

  • 我正在开发一个特性,使用Angular/预签名url和API Gateway/lambda生成预签名url将文件上传到S3。 我的工作流描述如下: 从模板中获取选定文件 请求我的api(网关/lambda)使用文件名生成预签名的URL。 const body={filename:this.selectedfile.name}const preSignedUrl=await this.http.po

  • 我正在尝试使用邮差上传一个文件。我已经通过点击“body”(在postman中)->二进制->选择文件附加了文件。我使用S3上载预签名的URL。在url中,文件的名称与我在Postman中选择的文件的名称完全相同。运行请求时,我得到一个错误: 但是,通过导出postman请求(通过单击“Code”)来获得curl命令,我得到了: 并添加一个用于上载文件的附加选项:

  • 问题内容: 我正在尝试使用预签名的URL将文件上传到Amazon的S3。我从生成URL的服务器获取URL,并将其作为JSON对象的一部分发送给我。我将URL作为字符串获取,如下所示: https://com-example-mysite.s3-us- east-1.amazonaws.com/userFolder/ImageName?X-Amz-Security- Token=xxfooxx%2F

  • 我上传一个文件到AmazonS3有问题。我开发了一个Grails RESTful服务,它使用AWS Java SDK生成预签名URL。当客户端上传一个文件时,它首先检索一个预签名的URL,然后使用这个将文件直接上传到我的S3 bucket。所以我有一个Grails服务,它创建了一个预签名的URL,如下所示...