From f7bfa9a080a3eeecc6034a3ad8ee5281d5529ac8 Mon Sep 17 00:00:00 2001 From: Phil Chen <06fahchen@gmail.com> Date: Thu, 21 Nov 2024 22:14:39 +0800 Subject: [PATCH] fix: prevent double encoding for aws url --- lib/req/utils.ex | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/req/utils.ex b/lib/req/utils.ex index ad2c5f3..a2884ae 100644 --- a/lib/req/utils.ex +++ b/lib/req/utils.ex @@ -36,7 +36,7 @@ defmodule Req.Utils do datetime = DateTime.truncate(datetime, :second) datetime_string = DateTime.to_iso8601(datetime, :basic) date_string = Date.to_iso8601(datetime, :basic) - url = URI.parse(url) + url = normalize_url(url) body_digest = options[:body_digest] || hex(sha256(body)) service = to_string(service) @@ -144,7 +144,7 @@ defmodule Req.Utils do datetime = DateTime.truncate(datetime, :second) datetime_string = DateTime.to_iso8601(datetime, :basic) date_string = Date.to_iso8601(datetime, :basic) - url = URI.parse(url) + url = normalize_url(url) service = to_string(service) canonical_query_string = @@ -204,6 +204,17 @@ defmodule Req.Utils do %{url | path: path, query: canonical_query_string <> "&X-Amz-Signature=#{signature}"} end + # Try decoding the path in case it was encoded earlier to prevent double encoding, + # as the path is encoded later in the corresponding function. + defp normalize_url(url) do + url = URI.parse(url) + + case url.path do + nil -> url + path -> %{url | path: URI.decode(path)} + end + end + defp canonical_host_header(headers, %URI{} = url) do {_host_headers, headers} = Enum.split_with(headers, &match?({"host", _value}, &1))