Current section
Files
Jump to
Current section
Files
src/aws4_request.erl
-module(aws4_request).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function]).
-export([sign/6]).
-spec sign(
gleam@http@request:request(bitstring()),
{{integer(), integer(), integer()}, {integer(), integer(), integer()}},
binary(),
binary(),
binary(),
binary()
) -> gleam@http@request:request(bitstring()).
sign(Request, Date_time, Access_key_id, Secret_access_key, Region, Service) ->
Payload_hash = gleam@string:lowercase(
binary:encode_hex(crypto:hash(sha256, erlang:element(4, Request)))
),
{{Year, Month, Day}, {Hour, Minute, Second}} = Date_time,
Date = gleam@string:concat(
[gleam@string:pad_left(gleam@int:to_string(Year), 4, <<"0"/utf8>>),
gleam@string:pad_left(gleam@int:to_string(Month), 2, <<"0"/utf8>>),
gleam@string:pad_left(gleam@int:to_string(Day), 2, <<"0"/utf8>>)]
),
Date_time@1 = gleam@string:concat(
[Date,
<<"T"/utf8>>,
gleam@string:pad_left(gleam@int:to_string(Hour), 2, <<"0"/utf8>>),
gleam@string:pad_left(gleam@int:to_string(Minute), 2, <<"0"/utf8>>),
gleam@string:pad_left(gleam@int:to_string(Second), 2, <<"0"/utf8>>),
<<"Z"/utf8>>]
),
Method = gleam@string:uppercase(
gleam@http:method_to_string(erlang:element(2, Request))
),
Headers = begin
_pipe = erlang:element(3, Request),
_pipe@1 = gleam@list:prepend(
_pipe,
{<<"x-amz-date"/utf8>>, Date_time@1}
),
_pipe@2 = gleam@list:prepend(
_pipe@1,
{<<"x-amz-content-sha256"/utf8>>, Payload_hash}
),
_pipe@3 = gleam@list:map(
_pipe@2,
fun(Header) ->
{gleam@string:lowercase(erlang:element(1, Header)),
erlang:element(2, Header)}
end
),
gleam@list:sort(
_pipe@3,
fun(A, B) ->
gleam@string:compare(erlang:element(1, A), erlang:element(1, B))
end
)
end,
Header_names = begin
_pipe@4 = Headers,
_pipe@5 = gleam@list:map(_pipe@4, fun(H) -> erlang:element(1, H) end),
gleam@string:join(_pipe@5, <<";"/utf8>>)
end,
Canonical_request = gleam@string:concat(
[Method,
<<"\n"/utf8>>,
erlang:element(8, Request),
<<"\n"/utf8>>,
gleam@option:unwrap(erlang:element(9, Request), <<""/utf8>>),
<<"\n"/utf8>>,
begin
_pipe@6 = Headers,
_pipe@7 = gleam@list:map(
_pipe@6,
fun(H@1) ->
<<<<(erlang:element(1, H@1))/binary, ":"/utf8>>/binary,
(erlang:element(2, H@1))/binary>>
end
),
gleam@string:join(_pipe@7, <<"\n"/utf8>>)
end,
<<"\n"/utf8>>,
<<"\n"/utf8>>,
Header_names,
<<"\n"/utf8>>,
Payload_hash]
),
Scope = gleam@string:concat(
[Date,
<<"/"/utf8>>,
Region,
<<"/"/utf8>>,
Service,
<<"/aws4_request"/utf8>>]
),
To_sign = gleam@string:concat(
[<<"AWS4-HMAC-SHA256"/utf8>>,
<<"\n"/utf8>>,
Date_time@1,
<<"\n"/utf8>>,
Scope,
<<"\n"/utf8>>,
gleam@string:lowercase(
binary:encode_hex(
crypto:hash(sha256, <<Canonical_request/binary>>)
)
)]
),
Key = begin
_pipe@8 = <<"AWS4"/utf8, Secret_access_key/binary>>,
_pipe@9 = gleam@crypto:hmac(<<Date/binary>>, sha256, _pipe@8),
_pipe@10 = gleam@crypto:hmac(<<Region/binary>>, sha256, _pipe@9),
_pipe@11 = gleam@crypto:hmac(<<Service/binary>>, sha256, _pipe@10),
gleam@crypto:hmac(<<"aws4_request"/utf8>>, sha256, _pipe@11)
end,
Signature = begin
_pipe@12 = <<To_sign/binary>>,
_pipe@13 = gleam@crypto:hmac(_pipe@12, sha256, Key),
_pipe@14 = binary:encode_hex(_pipe@13),
gleam@string:lowercase(_pipe@14)
end,
Authorization = gleam@string:concat(
[<<"AWS4-HMAC-SHA256 Credential="/utf8>>,
Access_key_id,
<<"/"/utf8>>,
Scope,
<<<<",SignedHeaders="/utf8, Header_names/binary>>/binary,
",Signature="/utf8>>,
Signature]
),
Headers@1 = [{<<"authorization"/utf8>>, Authorization} | Headers],
erlang:setelement(3, Request, Headers@1).