Skip to content

Commit d7906dc

Browse files
committed
put_aws_sigv4: Fix handling ?name (no value)
1 parent a01b032 commit d7906dc

File tree

2 files changed

+27
-36
lines changed

2 files changed

+27
-36
lines changed

lib/req/utils.ex

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,12 @@ defmodule Req.Utils do
7171

7272
path = URI.encode(url.path || "/", &(&1 == ?/ or URI.char_unreserved?(&1)))
7373

74+
canonical_query = canonical_query(url.query)
75+
7476
canonical_request = """
7577
#{method}
7678
#{path}
77-
#{url.query || ""}
79+
#{canonical_query}
7880
#{canonical_headers}
7981
8082
#{signed_headers}
@@ -106,6 +108,21 @@ defmodule Req.Utils do
106108
[{"authorization", authorization}] ++ aws_headers ++ headers
107109
end
108110

111+
defp canonical_query(query) when query in [nil, ""] do
112+
query
113+
end
114+
115+
defp canonical_query(query) do
116+
for item <- String.split(query, "&", trim: true) do
117+
case String.split(item, "=") do
118+
[name, value] -> [name, "=", value]
119+
[name] -> [name, "="]
120+
end
121+
end
122+
|> Enum.sort()
123+
|> Enum.intersperse("&")
124+
end
125+
109126
@doc """
110127
Create AWS Signature v4 URL.
111128

test/req/steps_test.exs

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -494,35 +494,20 @@ defmodule Req.StepsTest do
494494
end
495495

496496
describe "put_aws_sigv4" do
497-
# TODO: flaky
498-
@tag :skip
499497
test "body: binary" do
500498
plug = fn conn ->
501499
assert {:ok, "hello", conn} = Plug.Conn.read_body(conn)
502-
503-
assert Plug.Conn.get_req_header(conn, "x-amz-content-sha256") == [
504-
"2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
505-
]
506-
507-
assert Plug.Conn.get_req_header(conn, "authorization") == [
508-
"""
509-
AWS4-HMAC-SHA256 \
510-
Credential=foo/20240101/us-east-1/s3/aws4_request,\
511-
SignedHeaders=accept-encoding;host;user-agent;x-amz-content-sha256;x-amz-date,\
512-
Signature=a7a27655988cf90a6d834c6544e8a5e1ef00308a64692f0e656167165d42ec4d\
513-
"""
514-
]
515-
500+
assert ["AWS4-HMAC-SHA256" <> _] = Plug.Conn.get_req_header(conn, "authorization")
501+
assert [<<_::binary-size(64)>>] = Plug.Conn.get_req_header(conn, "x-amz-content-sha256")
516502
Plug.Conn.send_resp(conn, 200, "ok")
517503
end
518504

519505
req =
520506
Req.new(
521-
url: "http://localhost",
507+
url: "https://s3.amazonaws.com",
522508
aws_sigv4: [
523509
access_key_id: "foo",
524-
secret_access_key: "bar",
525-
datetime: ~U[2024-01-01 00:00:00Z]
510+
secret_access_key: "bar"
526511
],
527512
body: "hello",
528513
plug: plug
@@ -531,33 +516,22 @@ defmodule Req.StepsTest do
531516
assert Req.put!(req).body == "ok"
532517
end
533518

534-
# TODO: flaky
535-
@tag :skip
536519
test "body: enumerable" do
537520
plug = fn conn ->
538521
assert {:ok, "hello", conn} = Plug.Conn.read_body(conn)
539-
540-
assert Plug.Conn.get_req_header(conn, "x-amz-content-sha256") == ["UNSIGNED-PAYLOAD"]
541-
542-
assert Plug.Conn.get_req_header(conn, "authorization") == [
543-
"""
544-
AWS4-HMAC-SHA256 \
545-
Credential=foo/20240101/us-east-1/s3/aws4_request,\
546-
SignedHeaders=accept-encoding;content-length;host;user-agent;x-amz-content-sha256;x-amz-date,\
547-
Signature=6d8d9e360bf82d48064ee93cc628133da813bfc9b587fe52f8792c2335b29312\
548-
"""
549-
]
550-
522+
assert ["AWS4-HMAC-SHA256" <> _] = Plug.Conn.get_req_header(conn, "authorization")
523+
assert ["UNSIGNED-PAYLOAD"] = Plug.Conn.get_req_header(conn, "x-amz-content-sha256")
551524
Plug.Conn.send_resp(conn, 200, "ok")
552525
end
553526

554527
req =
555528
Req.new(
556-
url: "http://localhost",
529+
url: "http://example.com",
557530
aws_sigv4: [
558531
access_key_id: "foo",
559532
secret_access_key: "bar",
560-
datetime: ~U[2024-01-01 00:00:00Z]
533+
# test setting explicit :service
534+
service: :s3
561535
],
562536
headers: [content_length: 5],
563537
body: Stream.take(["hello"], 1),

0 commit comments

Comments
 (0)