diff --git a/content/s3-object.xqm b/content/s3-object.xqm index 2459731..fc0bec1 100644 --- a/content/s3-object.xqm +++ b/content/s3-object.xqm @@ -32,6 +32,37 @@ import module namespace aws-request = "http://history.state.gov/ns/xquery/aws/re import module namespace ec2-metadata = "http://history.state.gov/ns/xquery/aws/ec2/metadata"; import module namespace s3-request = "http://history.state.gov/ns/xquery/aws/s3/request"; +(: + : Encode object key names using the S3 API rules for using "UriEncode()" on object key names + : + : @see https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html + :) +declare function s3-object:encode-object-key-name($key-name as xs:string) { + $filename + => tokenize("/") + => for-each(function($slug) { encode-for-uri($slug) }) + => string-join("/") +}; + +(: + : Get binaries from S3 using STS tokens + : + : Adapted from object:get() +:) +declare function s3-object:get( + $bucket as xs:string, + $filename as xs:string +) { + let $credentials := ec2-metadata:get-credentials() + let $object-key-name := s3-object:encode-object-key-name($filename) + let $href := concat("https://s3.amazonaws.com/", $bucket, "/", $object-key-name) + let $parameters := + let $request := aws-request:create("GET", $href, $parameters) + let $signed-request := aws-request:sign($request, $bucket, $object-key-name, $credentials?AccessKeyId, $credentials?SecretAccessKey) + return + s3-request:send($signed-request) +}; + (: : Create and update binaries in S3 using STS tokens : @@ -43,7 +74,8 @@ declare function s3-object:put( $binary as xs:base64Binary ) { let $credentials := ec2-metadata:get-credentials() - let $href := concat("https://s3.amazonaws.com/", $bucket, "/", $filename) + let $object-key-name := s3-object:encode-object-key-name($filename) + let $href := concat("https://s3.amazonaws.com/", $bucket, "/", $object-key-name) let $parameters := let $file-extension := replace($filename, "^.+?(\.[a-z]+)$", "$1") let $content-type := @@ -61,7 +93,7 @@ declare function s3-object:put( let $request := aws-request:create("PUT", $href, $parameters) => aws-request:add-content-binary($binary, $content-type) - let $signed-request := aws-request:sign($request, $bucket, $filename, $credentials?AccessKeyId, $credentials?SecretAccessKey) + let $signed-request := aws-request:sign($request, $bucket, $object-key-name, $credentials?AccessKeyId, $credentials?SecretAccessKey) return s3-request:send($signed-request) }; @@ -76,10 +108,11 @@ declare function s3-object:delete( $filename as xs:string ) { let $credentials := ec2-metadata:get-credentials() - let $href := concat("https://s3.amazonaws.com/", $bucket, "/", $filename) + let $object-key-name := s3-object:encode-object-key-name($filename) + let $href := concat("https://s3.amazonaws.com/", $bucket, "/", $object-key-name) let $parameters := let $request := aws-request:create("DELETE", $href, $parameters) - let $signed-request := aws-request:sign($request, $bucket, $filename, $credentials?AccessKeyId, $credentials?SecretAccessKey) + let $signed-request := aws-request:sign($request, $bucket, $object-key-name, $credentials?AccessKeyId, $credentials?SecretAccessKey) return s3-request:send($signed-request) };