Câu hỏi Truy xuất các đối tượng của thùng mà không biết khu vực của nhóm với API REST AWS S3


Tôi đang cố gắng lấy các đối tượng của một thùng với API REST của AWS S3 (Tôi không sử dụng SDK) nhưng tiếc là tôi đang gặp vấn đề sau: Tôi không biết khu vực của nó khi tôi thực hiện cuộc gọi đến API.

Đây là những gì tôi làm:

  • Tôi tạo yêu cầu cho "https: // [bucketname] .s3.amazonaws.com /"
  • Tôi ký yêu cầu bằng vùng mặc định được đặt thành "us-west-1" (sử dụng quy trình chữ ký AWS4)
  • Nhưng hãy tưởng tượng cái xô tôi đang cố gắng để GET được đặt thành vùng "us-west-2", AWS đang ném cho tôi một lỗi

Vì vậy, đây là câu hỏi của tôi:

Có cách nào để có được một danh sách các đối tượng của một cái xô mà không biết khu vực của nó không? Hay có cách nào đơn giản để lấy vùng của một cái xô?

THÔNG TIN: Tôi đã đọc có hai kiểu để gọi một nhóm, "kiểu đường dẫn" và "kiểu được lưu trữ ảo", nhưng bất cứ khi nào tôi gửi yêu cầu tới "https://s3.amazonaws.com/ [bucketname] "thay vào đó nó mang lại cho tôi một lỗi chuyển hướng ...


7
2017-11-23 17:14


gốc




Các câu trả lời:


Xác thực AW4 V4 đòi hỏi bạn biết khu vực của nhóm để bạn có thể ký yêu cầu một cách chính xác. Nếu không thì:

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>

Chữ ký V2 không cụ thể theo vùng, vì vậy trước đây bạn có thể tìm hiểu vùng của nhóm bằng cách sử dụng yêu cầu V2:

http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketGETlocation.html

Tuy nhiên, có apprears là một catch-22 với V4, vì bạn phải biết khu vực của xô trước khi bạn có thể thực hiện cuộc gọi để khám phá khu vực của xô.

Giải pháp đầu tiên, sau đó là nắm bắt <Region> được trả về trong phản hồi lỗi và sử dụng vùng đó để ký các yêu cầu trong tương lai cho nhóm. Rõ ràng, bạn muốn lưu trữ thông tin này, vì không làm như vậy sẽ làm giảm hiệu suất và tăng chi phí.

Ngoài ra, có một cách để yêu cầu khu vực Tiêu chuẩn Hoa Kỳ (us-east-1) về vị trí của bất kỳ nhóm nào, ở bất kỳ khu vực nào, sử dụng định dạng URL này chỉ có:

https://s3.amazonaws.com/bucket-name?location

Ký yêu cầu này với khu vực phía đông-1 của chúng tôi và bạn sẽ nhận được phản hồi, bất cứ nơi nào có thể xảy ra. Lưu ý rằng nếu thùng ở phía đông-1 của chúng tôi (US-Standard) LocationConstraint được trả lại trống.

<?xml version="1.0" encoding="UTF-8"?>
<LocationConstraint xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  us-west-2
</LocationConstraint>

Bạn không thể sử dụng cấu trúc URL này để thực sự liệt kê các đối tượng nhóm trong các khu vực khác, vì https://s3.amazonaws.com/ luôn luôn định tuyến yêu cầu của bạn tới US-Standard (us-east-1) nhưng bạn có thể sử dụng nó để khám phá khu vực của bất kỳ nhóm nào vì American Standard có thông tin đó.


Cập nhật / Additonal

Tại một số thời điểm, S3 dường như đã thêm tiêu đề phản hồi mới, x-amx-bucket-region: cái nào xuất hiện là một bổ sung không có giấy tờ cho REST API, và xuất hiện được thêm vào nhiều phản hồi lỗi S3, đặc biệt là 403 lỗi.

Điều này có vẻ giống như một cơ chế hữu ích để tự điều chỉnh nếu bạn nhận được phản hồi lỗi.

Ngoài ra, thông tin trên về thẩm vấn khu vực tiêu chuẩn Hoa Kỳ về vị trí của bất kỳ nhóm nào vẫn chính xác và yêu cầu tương tự sẽ hoạt động nếu được gửi đến bất kỳ điểm cuối REST S3 khu vực nào, không chỉ US-Standard, vì tất cả các vùng đều biết vị trí của tất cả các nhóm khác: ví dụ https://s3-us-west-2.amazonaws.com/bucket-name?locationsẽ yêu cầu US-West-2 (Oregon), cũng có cùng thông tin, cho bất kỳ nhóm nào trên toàn cầu. Nó có thể là mong muốn trong một số trường hợp để thẩm vấn khu vực gần nhất của bạn.


11
2017-11-23 18:39



Cảm ơn rất nhiều Michael, đã giải quyết được vấn đề của tôi :) - Asticode


Bạn có thể lấy khu vực từ ngoại lệ -> chi tiết bổ sung

            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"));
            }

Nó không phải là cách tốt nhất để làm điều đó nhưng ngay bây giờ không có thay thế để làm điều đó.


1
2018-01-31 19:10





Nếu yêu cầu của bạn chỉ đơn giản là trỏ đến vùng sai, S3 sẽ trả lời bằng một tạm thời chuyển hướng. Vì bạn đã đề cập, nó trả lời bằng dài hạn chuyển hướng, cho biết yêu cầu không chính xác. S3 thường trả lời với một thông điệp hữu ích bên trong cơ thể phản hồi để giúp tìm ra vấn đề. Bạn muốn đọc nội dung phản hồi để sửa yêu cầu.


0
2017-11-23 18:36



Cảm ơn câu trả lời :) - Asticode


Trong Ruby, bạn có thể chuyển vùng như vậy khi nhận tài nguyên:

s3 = Aws::S3::Resource.new(region: 'us-west-2')

0
2018-03-31 20:37