【问题标题】:Why am I failing to read and write to Amazon S3 from a Delphi VCL application?为什么我无法从 Delphi VCL 应用程序读取和写入 Amazon S3?
【发布时间】:2020-04-15 09:16:18
【问题描述】:

我创建了一个 Delphi 应用程序,我想从该应用程序中读取和写入 Amazon S3(简单存储服务)存储桶。

在 S3 管理控制台中,我创建了一个新存储桶并将 Block all public access 设置为 On。

然后,我为 IAM(识别和访问管理)创建了一个新用户,并授予该用户 AmazonS3FullAccess 权限(目前)。在我的应用程序中,我将一个 TAmazonConnectionInfo 组件添加到我的项目中,并将 AccountKey 属性设置为秘密访问密钥,并将 AccountName 属性设置为我的该 IAM 用户的帐户密钥 ID。

在我的代码中,我正在实例化一个 TAmazonStorageService 类,在构造函数中将 TAmazonConnectionInfo 对象传递给它。然后我调用 UploadObject 方法,我将存储桶名称、对象名称和包含我要存储的对象的 TArray 传递给该方法。对 UploadObject 的调用返回 False。我尝试了几种不同的字节数组,其中一个基于我在这篇文章底部引用的一个 YouTube 视频中显示的示例,所以我很确定这不是我的对象的问题正在尝试存储。

我尝试将阻止所有公共访问设置为关闭,但这并没有解决问题。我不知道这些设置需要多长时间才能生效,但半小时后结果没有任何差异。

要么我没有充分配置我的 TAmazonConnectionInfo 对象,要么我需要将一个或多个对象添加到项目中,或者我需要在存储桶上执行一些配置。

我担心的一个问题是我的 S3 存储桶位于美国东部(俄亥俄)区域。 TAmazonConnectionInfo 组件的 Region 属性设置为 amzrUSEast1,但我不确定这是否正确。我尝试将 Region 设置为 amzrNotSpecified,但这并没有解决问题。

此外,我尝试根据 Paweł 的 cmets 将 StorageEndPoint 设置为 s3.us-east-2.amazonaws.com (http) 和 s3-accesspoint.us-east-2.amazonaws.com (https)。

我已经用尽了我的选择。如果您在使用 Delphi 的 S3 存储桶方面取得了成功,如果您能帮助我指出正确的方向,我将不胜感激。

我在 Windows 10 64 位上使用 Delphi Rio 10.3.3

参考资料:

https://www.youtube.com/watch?v=RUT9clew4PM&t=396s

https://www.youtube.com/watch?v=rtZkVAOvavU&t=1582s

https://www.youtube.com/watch?v=8VjTEtK_VaM&list=PLwUPJvR9mZHg3YgQKG8QCJAqdNxZyDVfg&index=50&t=0s

【问题讨论】:

  • 我认为这需要通过m r e进行重现的步骤
  • AWS 终端节点参考 (docs.aws.amazon.com/general/latest/gr/rande.html) 将美国东部(俄亥俄州)显示为 us-east-2。跟踪到更具体的端点,它会出现在 s3.us-east-2.amazonaws.com 上,所以看起来您尝试了正确的端点。
  • 回复 MartynA: 回复: 我的步骤产生了未知来源的失败。如果有人有一个实际工作的实例,那么有一个 m r e 会很棒。
  • 看起来 Delphi 通过硬编码亚马逊区域列表再次失败,因此不支持任何新区域。他们也懒得让它更新——us-east-2 于 2016 年秋季上线。
  • 查看源代码它所做的只是在枚举和文本值之间进行转换(例如 amzrUSEast1 变为 us-east-1 并用于构建 URL)。应该可以更改源以添加缺少的区域。

标签: amazon-web-services delphi amazon-s3


【解决方案1】:

下面的代码有效。插入您的 AccountName、AccountKey 和 BucketName 值并尝试一下。如果失败,请告诉我们它为您的回复返回了什么。

为了对此进行测试,我使用默认设置创建了一个新存储桶:美国东部(俄亥俄州)us-east-2 区域并选中阻止所有公共访问。我创建了一个具有编程访问权限的新用户,并为其分配了策略 AmazonS3FullAccess。

在我的初始测试中,我收到了这个 400 响应,通过设置 StorageEndpoint 解决了这个问题:

400: Bad Request - 授权标头格式错误;该区域 'us-east-1' 是错误的;期待'us-east-2' (AuthorizationHeaderMalformed)

如果您收到如下所示的 403 响应,请检查以确保用户政策(或您配置权限的方式)设置正确,并且您的 AccountName 和 AccountKey 正确。

403:禁止

program AmazonS3test;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Data.Cloud.CloudAPI, Data.Cloud.AmazonAPI, System.Classes;

const
  AccountName = ''; // IAM user Access key ID
  AccountKey = ''; // IAM user Secret access key
  BucketName = ''; // S3 bucket name
  StorageEndpoint = 's3-us-east-2.amazonaws.com';  // s3-<bucket region>.amazonaws.com
  ObjectName = 'TestFile.txt';
  MyString = 'Testing 1 2 3';

var
  ResponseInfo: TCloudResponseInfo;
  ConnectionInfo: TAmazonConnectionInfo;
  StorageService: TAmazonStorageService;
  StringStream: TStringStream;

begin
  ReportMemoryLeaksOnShutdown := True;

  ConnectionInfo := TAmazonConnectionInfo.Create(nil);
  StorageService := TAmazonStorageService.Create(ConnectionInfo);
  ResponseInfo := TCloudResponseInfo.Create;
  StringStream := TStringStream.Create(MyString);

  try
    try
      ConnectionInfo.AccountName := AccountName;
      ConnectionInfo.AccountKey := AccountKey;
      ConnectionInfo.StorageEndpoint := StorageEndpoint;

      StorageService.UploadObject(BucketName, ObjectName,
        StringStream.Bytes, True, nil, nil, amzbaPrivate, ResponseInfo);

      WriteLn('StatusCode: ' + IntToStr(ResponseInfo.StatusCode));
      WriteLn('Status    : ' + ResponseInfo.StatusMessage);
    except
      on E: Exception do
        WriteLn(E.ClassName, ': ', E.Message);
    end;
  finally
    StringStream.Free;
    ResponseInfo.Free;
    StorageService.Free;
    ConnectionInfo.Free;
  end;
end.

【讨论】:

  • 是的,它确实有效,我的代码也有效(终于!)。实际上,我认为我在此过程中搞砸了一些东西,所以我一步一步地创建了一个新的存储桶,这一次成功了。就其价值而言,您的代码和我的代码非常相似,尽管我感谢您使用 TCloudResponseInfo 实例,并将其添加到我的代码中。非常感谢您的帮助。感谢您的意见。
猜你喜欢
  • 2017-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
相关资源
最近更新 更多