From 7352b8cc3e2357b7e7a9880fb9ad13270545b95a Mon Sep 17 00:00:00 2001 From: Ransom Richardson Date: Mon, 28 May 2012 15:53:29 -0400 Subject: [PATCH 1/4] Simplify return of make_link --- src/erlcloud_s3.erl | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/erlcloud_s3.erl b/src/erlcloud_s3.erl index 28947653..7dad37d6 100644 --- a/src/erlcloud_s3.erl +++ b/src/erlcloud_s3.erl @@ -571,13 +571,13 @@ set_object_acl(BucketName, Key, ACL, Config) XMLText = list_to_binary(xmerl:export_simple([XML], xmerl_xml)), s3_simple_request(Config, put, BucketName, [$/|Key], "acl", [], XMLText, []). --spec make_link(integer(), string(), string()) -> {integer(), string(), string()}. +-spec make_link(integer(), string(), string()) -> iolist(). make_link(Expire_time, BucketName, Key) when is_integer(Expire_time), is_list(BucketName), is_list(Key) -> make_link(Expire_time, BucketName, Key, default_config()). --spec make_link(integer(), string(), string(), aws_config()) -> {integer(), string(), string()}. +-spec make_link(integer(), string(), string(), aws_config()) -> iolist(). make_link(Expire_time, BucketName, Key, Config) when is_integer(Expire_time), is_list(BucketName), is_list(Key) -> @@ -586,11 +586,10 @@ make_link(Expire_time, BucketName, Key, Config) Expires = integer_to_list(Expire_time + Datetime), To_sign = lists:flatten(["GET\n\n\n", Expires, "\n/", BucketName, "/", Key]), Sig = base64:encode(crypto:sha_mac(Config#aws_config.secret_access_key, To_sign)), - Host = lists:flatten(["http://", BucketName, ".", Config#aws_config.s3_host, port_spec(Config)]), - URI = lists:flatten(["/", Key, "?AWSAccessKeyId=", erlcloud_http:url_encode(Config#aws_config.access_key_id), "&Signature=", erlcloud_http:url_encode(Sig), "&Expires=", Expires]), - {list_to_integer(Expires), - binary_to_list(erlang:iolist_to_binary(Host)), - binary_to_list(erlang:iolist_to_binary(URI))}. + ["https://", BucketName, ".", Config#aws_config.s3_host, port_spec(Config), "/", Key, + "?AWSAccessKeyId=", erlcloud_http:url_encode(Config#aws_config.access_key_id), + "&Signature=", erlcloud_http:url_encode(Sig), + "&Expires=", Expires]. -spec set_bucket_attribute(string(), atom(), term()) -> ok. From 32c35d26769ace9eef0b266b9ee63b9842c29e90 Mon Sep 17 00:00:00 2001 From: Ransom Richardson Date: Mon, 24 Sep 2012 11:12:48 -0400 Subject: [PATCH 2/4] Add support for setting scheme --- include/erlcloud_aws.hrl | 1 + src/erlcloud_s3.erl | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/erlcloud_aws.hrl b/include/erlcloud_aws.hrl index b79a7bb3..a32433ea 100644 --- a/include/erlcloud_aws.hrl +++ b/include/erlcloud_aws.hrl @@ -1,5 +1,6 @@ -record(aws_config, { ec2_host="ec2.amazonaws.com"::string(), + s3_scheme="https://"::string(), s3_host="s3.amazonaws.com"::string(), s3_port=80::non_neg_integer(), sdb_host="sdb.amazonaws.com"::string(), diff --git a/src/erlcloud_s3.erl b/src/erlcloud_s3.erl index 7dad37d6..13b64790 100644 --- a/src/erlcloud_s3.erl +++ b/src/erlcloud_s3.erl @@ -586,7 +586,7 @@ make_link(Expire_time, BucketName, Key, Config) Expires = integer_to_list(Expire_time + Datetime), To_sign = lists:flatten(["GET\n\n\n", Expires, "\n/", BucketName, "/", Key]), Sig = base64:encode(crypto:sha_mac(Config#aws_config.secret_access_key, To_sign)), - ["https://", BucketName, ".", Config#aws_config.s3_host, port_spec(Config), "/", Key, + [Config#aws_config.s3_scheme, BucketName, ".", Config#aws_config.s3_host, port_spec(Config), "/", Key, "?AWSAccessKeyId=", erlcloud_http:url_encode(Config#aws_config.access_key_id), "&Signature=", erlcloud_http:url_encode(Sig), "&Expires=", Expires]. @@ -709,7 +709,7 @@ s3_request(Config, Method, Host, Path, Subresource, Params, POSTData, Headers) - _ -> [{"content-md5", binary_to_list(ContentMD5)}] end, RequestURI = lists:flatten([ - "https://", + Config#aws_config.s3_scheme, case Host of "" -> ""; _ -> [Host, $.] end, Config#aws_config.s3_host, port_spec(Config), EscapedPath, From c07d57d19947b3fc2b53001ff94039ebd611af7f Mon Sep 17 00:00:00 2001 From: Ransom Richardson Date: Thu, 27 Sep 2012 16:18:03 -0400 Subject: [PATCH 3/4] Handle user not being returned from list_objects --- src/erlcloud_s3.erl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/erlcloud_s3.erl b/src/erlcloud_s3.erl index 13b64790..38d7e824 100644 --- a/src/erlcloud_s3.erl +++ b/src/erlcloud_s3.erl @@ -270,6 +270,8 @@ extract_contents(Nodes) -> {owner, "Owner", fun extract_user/1}], [erlcloud_xml:decode(Attributes, Node) || Node <- Nodes]. +extract_user([]) -> + []; extract_user([Node]) -> Attributes = [{id, "ID", text}, {display_name, "DisplayName", optional_text}], From e71103747543bcb7810ece902ab48aa60e7a960a Mon Sep 17 00:00:00 2001 From: Ransom Richardson Date: Wed, 3 Oct 2012 13:51:08 -0400 Subject: [PATCH 4/4] revert change to make_link return value add make_get_url to return simplified url refactor to share code --- src/erlcloud_s3.erl | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/src/erlcloud_s3.erl b/src/erlcloud_s3.erl index 60162d00..f9f4459b 100644 --- a/src/erlcloud_s3.erl +++ b/src/erlcloud_s3.erl @@ -18,7 +18,8 @@ get_object_metadata/2, get_object_metadata/3, get_object_metadata/4, put_object/3, put_object/4, put_object/5, put_object/6, set_object_acl/3, set_object_acl/4, - make_link/3, make_link/4]). + make_link/3, make_link/4, + make_get_url/3, make_get_url/4]). -include_lib("erlcloud/include/erlcloud.hrl"). -include_lib("erlcloud/include/erlcloud_aws.hrl"). @@ -573,21 +574,40 @@ set_object_acl(BucketName, Key, ACL, Config) XMLText = list_to_binary(xmerl:export_simple([XML], xmerl_xml)), s3_simple_request(Config, put, BucketName, [$/|Key], "acl", [], XMLText, []). --spec make_link(integer(), string(), string()) -> iolist(). - -make_link(Expire_time, BucketName, Key) - when is_integer(Expire_time), is_list(BucketName), is_list(Key) -> - make_link(Expire_time, BucketName, Key, default_config()). - --spec make_link(integer(), string(), string(), aws_config()) -> iolist(). - -make_link(Expire_time, BucketName, Key, Config) +-spec sign_get(integer(), string(), string(), aws_config()) -> {string(), string()}. +sign_get(Expire_time, BucketName, Key, Config) when is_integer(Expire_time), is_list(BucketName), is_list(Key) -> {Mega, Sec, _Micro} = os:timestamp(), Datetime = (Mega * 1000000) + Sec, Expires = integer_to_list(Expire_time + Datetime), To_sign = lists:flatten(["GET\n\n\n", Expires, "\n/", BucketName, "/", Key]), Sig = base64:encode(crypto:sha_mac(Config#aws_config.secret_access_key, To_sign)), + {Sig, Expires}. + +-spec make_link(integer(), string(), string()) -> {integer(), string(), string()}. + +make_link(Expire_time, BucketName, Key) -> + make_link(Expire_time, BucketName, Key, default_config()). + +-spec make_link(integer(), string(), string(), aws_config()) -> {integer(), string(), string()}. + +make_link(Expire_time, BucketName, Key, Config) -> + {Sig, Expires} = sign_get(Expire_time, BucketName, Key, Config), + Host = lists:flatten(["http://", BucketName, ".", Config#aws_config.s3_host, port_spec(Config)]), + URI = lists:flatten(["/", Key, "?AWSAccessKeyId=", erlcloud_http:url_encode(Config#aws_config.access_key_id), "&Signature=", erlcloud_http:url_encode(Sig), "&Expires=", Expires]), + {list_to_integer(Expires), + binary_to_list(erlang:iolist_to_binary(Host)), + binary_to_list(erlang:iolist_to_binary(URI))}. + +-spec make_get_url(integer(), string(), string()) -> iolist(). + +make_get_url(Expire_time, BucketName, Key) -> + make_get_url(Expire_time, BucketName, Key, default_config()). + +-spec make_get_url(integer(), string(), string(), aws_config()) -> iolist(). + +make_get_url(Expire_time, BucketName, Key, Config) -> + {Sig, Expires} = sign_get(Expire_time, BucketName, Key, Config), [Config#aws_config.s3_scheme, BucketName, ".", Config#aws_config.s3_host, port_spec(Config), "/", Key, "?AWSAccessKeyId=", erlcloud_http:url_encode(Config#aws_config.access_key_id), "&Signature=", erlcloud_http:url_encode(Sig),