diff --git a/lib/req/utils.ex b/lib/req/utils.ex index aa35d4c..1590ae9 100644 --- a/lib/req/utils.ex +++ b/lib/req/utils.ex @@ -58,9 +58,11 @@ defmodule Req.Utils do canonical_headers = Enum.map_intersperse(canonical_headers, "\n", fn {name, value} -> [name, ":", value] end) + path = URI.encode(url.path || "/", &(&1 == ?/ or URI.char_unreserved?(&1))) + canonical_request = """ #{method} - #{url.path || "/"} + #{path} #{url.query || ""} #{canonical_headers} @@ -137,6 +139,8 @@ defmodule Req.Utils do &String.downcase(elem(&1, 0), :ascii) ) + path = URI.encode(url.path || "/", &(&1 == ?/ or URI.char_unreserved?(&1))) + true = url.query in [nil, ""] method = method |> Atom.to_string() |> String.upcase() @@ -146,7 +150,7 @@ defmodule Req.Utils do canonical_request = """ #{method} - #{url.path || "/"} + #{path} #{canonical_query_string} #{canonical_headers} diff --git a/test/req/utils_test.exs b/test/req/utils_test.exs index 1749998..7287bab 100644 --- a/test/req/utils_test.exs +++ b/test/req/utils_test.exs @@ -15,7 +15,7 @@ defmodule Req.UtilsTest do service: "s3", datetime: ~U[2024-01-01 09:00:00Z], method: :get, - url: "https://s3", + url: "https://s3/foo/:bar", headers: [{"host", "s3"}], body: "" ] @@ -50,20 +50,20 @@ defmodule Req.UtilsTest do service: "s3", datetime: ~U[2024-01-01 09:00:00Z], method: :get, - url: "https://s3" + url: "https://s3/foo/:bar" ] url1 = to_string(Req.Utils.aws_sigv4_url(options)) url2 = """ - https://s3?\ + https://s3/foo/:bar?\ X-Amz-Algorithm=AWS4-HMAC-SHA256\ &X-Amz-Credential=dummy-access-key-id%2F20240101%2Fdummy-region%2Fs3%2Faws4_request\ &X-Amz-Date=20240101T090000Z\ &X-Amz-Expires=86400\ &X-Amz-SignedHeaders=host\ - &X-Amz-Signature=684b112675beaf7f858dbf650cc12c5aa3d0eeb15fa4038ea809149f3c6476e3\ + &X-Amz-Signature=7fd16f0749b0902acde5a3d8933315006f2993b279b995cad880165ff4be75ff\ """ assert url1 == url2