我尝试使用AWS S3 REST API检索存储桶的对象(我没有使用SDK)但不幸的是我遇到了以下问题:我没有&#39 ;当我调用API时,我知道它的区域。
这就是我的所作所为:
因此,我的问题是:
有没有办法在不知道其区域的情况下获取桶的对象列表?或者有没有简单的方法来获取桶的区域?
信息:我读过有两种叫斗的风格,"路径风格"和"虚拟托管式",但每当我将请求发送到" https://s3.amazonaws.com/ [bucketname]"相反,它给了我一个重定向永久错误...
答案 0 :(得分:11)
AWS V4身份验证要求您知道存储区的区域,以便您可以正确签署请求。否则:
HTTP/1.1 400 Bad Request
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>AuthorizationHeaderMalformed</Code>
<Message>The authorization header is malformed; the region 'us-east-1' is wrong; expecting 'us-west-2'</Message>
<Region>us-west-2</Region>
<RequestId>xxxx</RequestId>
<HostId>xxxx</HostId>
</Error>
V2签名不是特定于区域的,所以以前有一种简单的方法可以使用V2请求来学习桶的区域:
http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html
但是,有一个关于V4的捕获22,因为你必须知道桶的区域才能调用以发现桶的区域。
然后,第一个解决方案是捕获错误响应中返回的<Region>
,并使用该区域来标记存储桶的未来请求。显然,您希望缓存此信息,因为不这样做会降低性能并增加成本。
或者,有一种方法可以使用此URL格式 向美国标准区域(us-east-1)询问任何区域中任何存储桶的位置:
https://s3.amazonaws.com/bucket-name?location
使用us-east-1区域签署此请求,无论桶在哪里,您都会得到响应。请注意,如果存储桶位于us-east-1(美国标准版)中,则LocationConstraint
将返回空。
<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
us-west-2
</LocationConstraint>
您不能使用此URL构造实际列出其他区域中的存储桶对象,因为https://s3.amazonaws.com/
始终将您的请求路由到US-Standard(us-east-1),但您可以使用它来发现任何区域因为美国标准有这方面的信息。
<强>更新/产生额外强>
在某些时候,S3似乎添加了一个新的响应标头,x-amx-bucket-region:
出现,作为REST API的未记录添加,出现要添加到许多S3错误响应中,特别是403错误。
如果收到错误回复,这似乎是一种有用的自我纠正机制。
此外,上述有关询问美国标准区域任何桶位置的信息仍然准确,如果发送到任何区域S3 REST端点,而不仅仅是美国标准,则相同的请求应该有效,因为所有地区知道所有其他桶的位置:例如https://s3-us-west-2.amazonaws.com/bucket-name?location
会询问US-West-2(俄勒冈州),它也有相同的信息,可用于全球任何一个桶。在某些情况下,可能需要询问最近的地区。
答案 1 :(得分:1)
您可以从例外中获取该区域 - &gt;其他细节
AmazonS3 client = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials)).withRegion(Regions.US_EAST_1).build();
Regions bucketRegion = Regions.US_EAST_1;
try {
client.getBucketLocation(bucket.getName());
} catch (AmazonS3Exception e) {
bucketRegion = Regions.fromName(e.getAdditionalDetails().get("Region"));
}
这不是最好的方法,但现在没有别的选择。
答案 2 :(得分:0)
如果您的请求只是指向错误的区域,则S3会以临时重定向进行响应。由于您提到它使用永久重定向进行回复,因此表明请求不正确。 S3通常会在响应正文中回复一条有用的消息,以帮助找出问题所在。您需要阅读响应正文以更正请求。
答案 3 :(得分:0)
在Ruby中,您可以在获取资源时传递区域:
s3 = Aws::S3::Resource.new(region: 'us-west-2')
答案 4 :(得分:0)
在@ patrice-gagnon响应之后,我将区域配置注入到AWS实例中,并且对我有用。
通过我在NestJS中使用Typescript的方式
const s3 = new AWS.S3({ region: 'eu-west-3' });