@@ -157,7 +157,10 @@ fn uri_from_s3_notification(message: &[u8], ack_id: &str) -> Result<Uri, PreProc
157
157
let bucket = value[ "Records" ] [ 0 ] [ "s3" ] [ "bucket" ] [ "name" ]
158
158
. as_str ( )
159
159
. context ( "invalid S3 notification: Records[0].s3.bucket.name not found" ) ?;
160
- Uri :: from_str ( & format ! ( "s3://{}/{}" , bucket, key) ) . map_err ( |e| e. into ( ) )
160
+ let encoded_key = percent_encoding:: percent_decode ( key. as_bytes ( ) )
161
+ . decode_utf8 ( )
162
+ . context ( "invalid S3 notification: Records[0].s3.object.key could not be url decoded" ) ?;
163
+ Uri :: from_str ( & format ! ( "s3://{}/{}" , bucket, encoded_key) ) . map_err ( |e| e. into ( ) )
161
164
}
162
165
163
166
/// A message for which we know as much of the global processing status as
@@ -344,4 +347,51 @@ mod tests {
344
347
panic ! ( "Expected skippable error" ) ;
345
348
}
346
349
}
350
+
351
+ #[ test]
352
+ fn test_uri_from_s3_notification_url_decode ( ) {
353
+ let test_message = r#"
354
+ {
355
+ "Records": [
356
+ {
357
+ "eventVersion": "2.1",
358
+ "eventSource": "aws:s3",
359
+ "awsRegion": "us-west-2",
360
+ "eventTime": "2021-05-22T09:22:41.789Z",
361
+ "eventName": "ObjectCreated:Put",
362
+ "userIdentity": {
363
+ "principalId": "AWS:AIDAJDPLRKLG7UEXAMPLE"
364
+ },
365
+ "requestParameters": {
366
+ "sourceIPAddress": "127.0.0.1"
367
+ },
368
+ "responseElements": {
369
+ "x-amz-request-id": "C3D13FE58DE4C810",
370
+ "x-amz-id-2": "FMyUVURIx7Zv2cPi/IZb9Fk1/U4QfTaVK5fahHPj/"
371
+ },
372
+ "s3": {
373
+ "s3SchemaVersion": "1.0",
374
+ "configurationId": "testConfigRule",
375
+ "bucket": {
376
+ "name": "mybucket",
377
+ "ownerIdentity": {
378
+ "principalId": "A3NL1KOZZKExample"
379
+ },
380
+ "arn": "arn:aws:s3:::mybucket"
381
+ },
382
+ "object": {
383
+ "key": "hello%3A%3Aworld%3A%3Alogs.json",
384
+ "size": 1024,
385
+ "eTag": "d41d8cd98f00b204e9800998ecf8427e",
386
+ "versionId": "096fKKXTRTtl3on89fVO.nfljtsv6qko",
387
+ "sequencer": "0055AED6DCD90281E5"
388
+ }
389
+ }
390
+ }
391
+ ]
392
+ }"# ;
393
+ let actual_uri = uri_from_s3_notification ( test_message. as_bytes ( ) , "myackid" ) . unwrap ( ) ;
394
+ let expected_uri = Uri :: from_str ( "s3://mybucket/hello::world::logs.json" ) . unwrap ( ) ;
395
+ assert_eq ! ( actual_uri, expected_uri) ;
396
+ }
347
397
}
0 commit comments