9
9
-module (aws_s3_presigned_url ).
10
10
11
11
-export ([ make_presigned_v4_url /5 ,
12
- make_presigned_v4_url /6
12
+ make_presigned_v4_url /6 ,
13
+ make_presigned_v4_url /7
13
14
]).
14
15
15
16
-include_lib (" hackney/include/hackney_lib.hrl" ).
@@ -23,6 +24,11 @@ make_presigned_v4_url(Client0, Method, ExpireSeconds, Bucket, Key) ->
23
24
24
25
-spec make_presigned_v4_url (map (), get | put , integer (), binary (), binary (),path |virtual_host ) -> {ok , binary ()}.
25
26
make_presigned_v4_url (Client0 , Method , ExpireSeconds , Bucket , Key , Style ) ->
27
+ make_presigned_v4_url (Client0 , Method , ExpireSeconds , Bucket , Key , Style , undefined ).
28
+
29
+ -spec make_presigned_v4_url (map (), get | put , integer (), binary (), binary (), path |virtual_host , undefined |binary ()) ->
30
+ {ok , binary ()}.
31
+ make_presigned_v4_url (Client0 , Method , ExpireSeconds , Bucket , Key , Style , Tags ) ->
26
32
MethodBin = aws_request :method_to_binary (Method ),
27
33
Path = build_path (Client0 ,Bucket ,Key ,Style ),
28
34
Client = Client0 #{service => <<" s3" >>},
@@ -38,12 +44,20 @@ make_presigned_v4_url(Client0, Method, ExpireSeconds, Bucket, Key, Style) ->
38
44
, {body_digest , <<" UNSIGNED-PAYLOAD" >>}
39
45
, {uri_encode_path , false } % % We already encode in build_path/4
40
46
],
41
- Options = case SecurityToken of
42
- undefined ->
43
- Options0 ;
44
- _ ->
45
- [{session_token , hackney_url :urlencode (SecurityToken )} | Options0 ]
46
- end ,
47
+ Options1 =
48
+ case SecurityToken of
49
+ undefined ->
50
+ Options0 ;
51
+ _ ->
52
+ [{session_token , hackney_url :urlencode (SecurityToken )} | Options0 ]
53
+ end ,
54
+ Options =
55
+ case Tags of
56
+ undefined ->
57
+ Options1 ;
58
+ _ ->
59
+ [{tags , Tags } | Options1 ]
60
+ end ,
47
61
{ok , aws_signature :sign_v4_query_params (AccessKeyID , SecretAccessKey , Region , Service , Now , MethodBin , URL , Options )}.
48
62
49
63
% %====================================================================
@@ -197,4 +211,26 @@ presigned_url_virtual_host_style_test() ->
197
211
? assertEqual (<<" 3600" >>, proplists :get_value (<<" X-Amz-Expires" >>, ParsedQs )),
198
212
? assertEqual (<<" Token" >>, proplists :get_value (<<" X-Amz-Security-Token" >>, ParsedQs )),
199
213
? assertEqual (<<" host" >>, proplists :get_value (<<" X-Amz-SignedHeaders" >>, ParsedQs )).
214
+
215
+ presigned_url_tags_test () ->
216
+ Client = aws_client :make_temporary_client (<<" AccessKeyID" >>, <<" SecretAccessKey" >>,
217
+ <<" Token" >>, <<" eu-west-1" >>),
218
+ {ok , Url } = aws_s3_presigned_url :make_presigned_v4_url (Client , put , 3600 , <<" bucket" >>, <<" key" >>, path , <<" key1=value1&key2=value2" >>),
219
+ HackneyUrl = hackney_url :parse_url (Url ),
220
+ ParsedQs = hackney_url :parse_qs (HackneyUrl # hackney_url .qs ),
221
+ Credential = proplists :get_value (<<" X-Amz-Credential" >>, ParsedQs ),
222
+ [AccessKeyId , _ShortDate , Region , Service , Request ] = binary :split (Credential , <<" /" >>, [global ]),
223
+ ? assertEqual (https , HackneyUrl # hackney_url .scheme ),
224
+ ? assertEqual (443 , HackneyUrl # hackney_url .port ),
225
+ ? assertEqual (" s3.eu-west-1.amazonaws.com" , HackneyUrl # hackney_url .host ),
226
+ ? assertEqual (<<" /bucket/key" >>, HackneyUrl # hackney_url .path ),
227
+ ? assertEqual (7 , length (ParsedQs )),
228
+ ? assertEqual (<<" AccessKeyID" >>, AccessKeyId ),
229
+ ? assertEqual (<<" eu-west-1" >>, Region ),
230
+ ? assertEqual (<<" s3" >>, Service ),
231
+ ? assertEqual (<<" aws4_request" >>, Request ),
232
+ ? assertEqual (<<" AWS4-HMAC-SHA256" >>, proplists :get_value (<<" X-Amz-Algorithm" >>, ParsedQs )),
233
+ ? assertEqual (<<" 3600" >>, proplists :get_value (<<" X-Amz-Expires" >>, ParsedQs )),
234
+ ? assertEqual (<<" Token" >>, proplists :get_value (<<" X-Amz-Security-Token" >>, ParsedQs )),
235
+ ? assertEqual (<<" host;x-amz-tagging" >>, proplists :get_value (<<" X-Amz-SignedHeaders" >>, ParsedQs )).
200
236
-endif .
0 commit comments