С Webhooks для S3, используя API, можно настраивать отправку таких HTTP и HTTPS запросов по событиям для бакета, как:
- обработка и конвертирование файлов после загрузки;
- интегрирование с разными внешними системами;
- логирование для объектного хранилища.
События (Event), для которых можно настроить конфигурацию Webhooks:
- s3:ObjectCreated:* — PutObject, PutObjectCopy, CompleteMultipartUpload.
- s3:ObjectCreated:Put — PutObject.
- s3:ObjectCreated:Copy — PutObjectCopy.
- s3:ObjectCreated:CompleteMultipartUpload — CompleteMultipartUpload.
- s3:ObjectRemoved:* — DeleteObject.
- s3:ObjectRemoved:Delete — DeleteObject.
Для работы с Webhooks доступно два метода:
- PutBucketNotificationConfiguration;
- GetBucketNotificationConfiguration.
Общая XML-конфигурация
1PUT /?notification HTTP/1.1
2Host: Bucket.hb.bizmrg.com
3
4<?xml version="1.0" encoding="UTF-8"?>
5<NotificationConfiguration xmlns="https://s3.amazonaws.com/doc/2006-03-01/">
6 <SimpleTopicConfiguration>
7 <Id>string</Id>
8 <Url>string</Url>
9 <Event>string</Event>
10 ...
11 <Filter>
12 <S3Key>
13 <FilterRule>
14 <Name>string</Name>
15 <Value>string</Value>
16 </FilterRule>
17 ...
18 </S3Key>
19 </Filter>
20 </SimpleTopicConfiguration>
21 ...
22</NotificationConfiguration>
Put Bucket Notification Configuration
Используя метод PUT можно настроить уведомления о некоторых событиях (PutObject, DeleteObject и т.д) в бакете.
Сейчас поддерживается один тип событий — SimpleTopicConfiguration — запрос на url, предоставленный пользователем.
Например, необходимо выполнить запрос на url https://test.com при PutObject в бакет bucketA объектов, имена которых подходят под маску image/*.png.
Запрос:
1PUT /?notification HTTP/1.1
2Host: bucketA.hb.bizmrg.com
3Content-Length: 606
4Content-Type: application/xml
5x-amz-content-sha256: 34850007f92ec3331486b48fd7db15f48315fe73c4a9b135e6d9fd629276c1e7
6x-amz-date: 20200831T000345Z
7Authorization: AWS4-HMAC-SHA256 Credential=II5JDQBAN3JYM4DNEB6C/20200831/ru-msk/s3/aws4_request,SignedHeaders=content-md5;content-type;host;x-amz-content-sha256;x-amz-date,Signature=fc07a541c2acdbf7527eba358afa0a6d460c9bfec539dd29dfa6b5b854aae109
8
9<?xml version="1.0" encoding="UTF-8"?>
10<NotificationConfiguration xmlns="https://s3.amazonaws.com/doc/2006-03-01/">
11 <SimpleTopicConfiguration>
12 <Id>1</Id>
13 <Event>s3:ObjectCreated:Put</Event>
14 <Url>https://test.com</Url>
15 <Filter>
16 <S3Key>
17 <FilterRule>
18 <Name>Prefix</Name>
19 <Value>image/</Value>
20 </FilterRule>
21 <FilterRule>
22 <Name>Suffix</Name>
23 <Value>.png</Value>
24 </FilterRule>
25 </S3Key>
26 </Filter>
27 </SimpleTopicConfiguration>
28</NotificationConfiguration>
Ответ:
HTTP/1.1 200 OK
Date: Mon, 31 Aug 2020 17:31:43 GMT
x-amz-request-id: tx00000000000000010ad2b-005a6135e2-f647d-ru-mska
Content-Length: 0
Content-Type: application/xml
Connection: close
GetBucketNotificationConfiguration
Метод GET возвращает текущую конфигурацию правил (SimpleNotificationConfiguration) бакета. Если же правила для данного бакета не были установлены, то будет возращен пустой элемент NotificationConfiguration.
Запрос:
GET /?notification HTTP/1.1
Host: my-test-bucket1.hb.bizmrg.com
Content-Length: 0
Content-Type: application/xml
x-amz-content-sha256: 34850007f92ec3331486b48fd7db15f48315fe73c4a9b135e6d9fd629276c1e7
x-amz-date: 20200831T000345Z
Authorization: AWS4-HMAC-SHA256 Credential=II5JDQBAN3JYM4DNEB6C/20200831/ru-msk/s3/aws4_request,SignedHeaders=content-md5;content-type;host;x-amz-content-sha256;x-amz-date,Signature=fc07a541c2acdbf7527eba358afa0a6d460c9bfec539dd29dfa6b5b854aae109
Ответ:
1HTTP/1.1 200
2Date: Mon, 31 Aug 2020 17:31:43 GMT
3x-amz-request-id: tx00000000000000010ad2b-005a6135e2-f647d-ru-mska
4Content-Length: 1031
5Content-Type: application/xml
6Connection: close
7
8<?xml version="1.0" encoding="UTF-8"?>
9<NotificationConfiguration>
10 <SimpleTopicConfiguration>
11 <Id>1</Id>
12 <Event>s3:ObjectCreated:Put</Event>
13 <Url>https://test321.com</Url>
14 <Filter>
15 <S3Key>
16 <FilterRule>
17 <Name>Prefix</Name>
18 <Value>image/</Value>
19 </FilterRule>
20 <FilterRule>
21 <Name>Suffix</Name>
22 <Value>.png</Value>
23 </FilterRule>
24 </S3Key>
25 </Filter>
26 </SimpleTopicConfiguration>
27 <SimpleTopicConfiguration>
28 <Id>2</Id>
29 <Event>s3:ObjectRemoved:Delete</Event>
30 <Url>https://test123.com</Url>
31 <Filter>
32 <S3Key>
33 <FilterRule>
34 <Name>Prefix</Name>
35 <Value>image/</Value>
36 </FilterRule>
37 <FilterRule>
38 <Name>Suffix</Name>
39 <Value>.png</Value>
40 </FilterRule>
41 </S3Key>
42 </Filter>
43 </SimpleTopicConfiguration>
44</NotificationConfiguration>
Пример выполнения Webhook
Для примера установленных правил, при загрузкие объектов в бакет bucketA с именами image/*.png, будет приходить следующий запрос:
1POST <url> HTTP/1.1
2x-amz-sns-messages-type: SubscriptionConfirmation
3
4{ "Records":
5 [
6 {
7 "s3": {
8 "object": {
9 "eTag":"aed563ecafb4bcc5654c597a421547b2",
10 "sequencer":1577453615,
11 "key":"some-file-to-bucket",
12 "size":100
13 },
14 "configurationId":"1",
15 "bucket": {
16 "name": "bucketA",
17 "ownerIdentity": {
18 "principalId":"mcs2883541269"}
19 },
20 "s3SchemaVersion":"1.0"
21 },
22 "eventVersion":"1.0",
23 "requestParameters":{
24 "sourceIPAddress":"185.6.245.156"
25 },
26 "userIdentity": {
27 "principalId":"2407013e-cbc1-415f-9102-16fb9bd6946b"
28 },
29 "eventName":"s3:ObjectCreated:Put",
30 "awsRegion":"ru-msk",
31 "eventSource":"aws:s3",
32 "responseElements": {
33 "x-amz-request-id":"VGJR5rtJ"
34 }
35 }
36 ]
37}
В процессе выполнения запроса сервис LinxCloud S3 валидирует url, выполняя на него запрос(2):
1POST https://test.com HTTP/1.1
2x-amz-sns-messages-type: SubscriptionConfirmation
3content-type: application/json
4
5{
6 "Timestamp":"2019-12-26T19:29:12+03:00",
7 "Type":"SubscriptionConfirmation",
8 "Message":"You have chosen to subscribe to the topic $topic. To confirm the subscription you need to response with calculated signature",
9 "TopicArn":"mcs2883541269|bucketA|s3:ObjectCreated:Put",
10 "SignatureVersion":1,
11 "Token":"RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA"
12}
Чтобы подтвердить url нужно в ответ отправить подпись:
1content-type: application/json
2
3{"signature":"ea3fce4bb15c6de4fec365d36bcebbc34ccddf54616d5ca12e1972f82b6d37af"}
Формула для вычисления сигнатуры:
signature = hmacsha256(_url, hmacsha256(_TopicArn, hmacsha256(_Timestamp, Token)))
Для приведенного примера:
signature = hmac_sha256_hex(“https://test.com”, hmac_sha256(“mcs2883541269|bucketA|s3:ObjectCreated:Put”, hmac_sha256(“2019-12-26T19:29:12+03:00”, “RPE5UuG94rGgBH6kHXN9FUPugFxj1hs2aUQc99btJp3E49tA”)))
Ответ на запрос(1), при успешном подтверждении url, будет отправлен response:
HTTP/1.1 200