@@ -157,7 +157,10 @@ fn uri_from_s3_notification(message: &[u8], ack_id: &str) -> Result<Uri, PreProc
157157 let bucket = value[ "Records" ] [ 0 ] [ "s3" ] [ "bucket" ] [ "name" ]
158158 . as_str ( )
159159 . 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 ( ) )
161164}
162165
163166/// A message for which we know as much of the global processing status as
@@ -344,4 +347,51 @@ mod tests {
344347 panic ! ( "Expected skippable error" ) ;
345348 }
346349 }
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+ }
347397}
0 commit comments