Skip to content

Commit 8b77c41

Browse files
author
Shunichi Shinohara
committed
Add PUT Copy operation
Before this commit, cs driver uses stanchion's function to calculate S3 signature. Because PUT Copy API uses x-amz-* headers, it become unappropriate. So it is replaced by the function copied from erlcloud and simplified one.
1 parent d6bb830 commit 8b77c41

1 file changed

Lines changed: 51 additions & 7 deletions

File tree

src/basho_bench_driver_cs.erl

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ run2(delete, KeyGen, _ValueGen, #state{bucket = Bucket} = State) ->
191191
{error, Reason} ->
192192
{error, Reason, S2}
193193
end;
194+
run2(copy, KeyGen, _ValueGen, #state{bucket = Bucket} = State) ->
195+
{NextHost, S2} = next_host(State),
196+
{Host, Port} = NextHost,
197+
SourceKey = KeyGen(),
198+
DestKey = SourceKey ++ basho_bench_config:get(cs_copy_suffix, "-copy"),
199+
Url = url(Host, Port, Bucket, DestKey),
200+
Headers = [{"x-amz-copy-source", "/" ++ Bucket ++ "/" ++ SourceKey}],
201+
case do_copy({Host, Port}, Url, Headers, State) of
202+
ok ->
203+
{ok, S2};
204+
{error, Reason} ->
205+
{error, Reason, S2}
206+
end;
194207
run2(Op, _KeyGen, _ValueGen, State) ->
195208
{error, {unknown_op, Op}, State}.
196209

@@ -422,6 +435,16 @@ do_delete(Host, Url, Headers, State) ->
422435
{error, Reason}
423436
end.
424437

438+
do_copy(Host, Url, Headers, State) ->
439+
case send_request(Host, Url, Headers, put, <<>>, proxy_opts(State)) of
440+
{ok, "200", _Header, _Body} ->
441+
ok;
442+
{ok, Code, _Header, _Body} ->
443+
{error, {http_error, Code}};
444+
{error, Reason} ->
445+
{error, Reason}
446+
end.
447+
425448
do_get_first_unit(Host, Url, Headers, State) ->
426449
BufSize = 128*1024,
427450
Opts = [{max_pipeline_size, 9999999},
@@ -516,19 +539,40 @@ initiate_request(Host, Url, Headers0, Method, Body, Options) ->
516539
'Content-Type', Headers0,
517540
'application/octet-stream')),
518541
Date = httpd_util:rfc1123_date(),
542+
Uri = element(7, Url),
519543
Headers = [{'Content-Type', ContentTypeStr},
520544
{'Date', Date}|lists:keydelete('Content-Type', 1, Headers0)],
521-
Uri = element(7, Url),
522-
Sig = stanchion_auth:request_signature(
523-
uppercase_verb(Method), Headers, Uri,
524-
basho_bench_config:get(cs_secret_key, "undefined")),
525-
AuthStr = ["AWS ", basho_bench_config:get(cs_access_key, "undefined"), ":", Sig],
526-
HeadersWithAuth = [{'Authorization', AuthStr}|Headers],
545+
HeadersWithAuth =
546+
case basho_bench_config:get(cs_access_key, undefined) of
547+
undefined ->
548+
Headers;
549+
AccessKey ->
550+
AuthSig = auth_sig(AccessKey, basho_bench_config:get(cs_secret_key),
551+
uppercase_verb(Method), ContentTypeStr, Date,
552+
Headers, Uri),
553+
[{'Authorization', AuthSig}|Headers]
554+
end,
527555
Timeout = basho_bench_config:get(cs_request_timeout, 5000),
528556
ibrowse_http_client:send_req(Pid, Url, HeadersWithAuth, Method,
529557
Body, Options, Timeout).
530558

531-
%% Setup user, not related to load operations
559+
%% S3 utilities
560+
561+
auth_sig(AccessKey, SecretKey, Method, ContentType, Date, Headers, Resource) ->
562+
AmzHeaders = lists:filter(fun ({"x-amz-" ++ _, V}) when V =/= undefined -> true; (_) -> false end, Headers),
563+
CanonizedAmzHeaders =
564+
[[Name, $:, Value, $\n] || {Name, Value} <- lists:sort(AmzHeaders)],
565+
StringToSign = [string:to_upper(atom_to_list(Method)), $\n,
566+
"", $\n, % Content-MD5
567+
ContentType, $\n,
568+
Date, $\n,
569+
CanonizedAmzHeaders,
570+
Resource
571+
],
572+
Signature = base64:encode(stanchion_utils:sha_mac(SecretKey, StringToSign)),
573+
["AWS ", AccessKey, $:, Signature].
574+
575+
%% CS utilities
532576

533577
setup_user_and_bucket(State) ->
534578
case basho_bench_config:get(cs_access_key, undefined) of

0 commit comments

Comments
 (0)