diff --git a/lib/ex_aws/s3.ex b/lib/ex_aws/s3.ex index 96d6ae5..972cc9e 100644 --- a/lib/ex_aws/s3.ex +++ b/lib/ex_aws/s3.ex @@ -1367,9 +1367,9 @@ defmodule ExAws.S3 do def presigned_url(config, http_method, bucket, object, opts \\ []) do expires_in = Keyword.get(opts, :expires_in, 3600) query_params = Keyword.get(opts, :query_params, []) - virtual_host = Keyword.get(opts, :virtual_host, false) + virtual_host = Keyword.get(opts, :virtual_host, config[:virtual_host] || false) s3_accelerate = Keyword.get(opts, :s3_accelerate, false) - bucket_as_host = Keyword.get(opts, :bucket_as_host, false) + bucket_as_host = Keyword.get(opts, :bucket_as_host, config[:bucket_as_host] || false) headers = Keyword.get(opts, :headers, []) {config, virtual_host} = @@ -1431,9 +1431,9 @@ defmodule ExAws.S3 do ) :: presigned_post_result() def presigned_post(config, bucket, key, opts \\ []) do expires_in = Keyword.get(opts, :expires_in, 3600) - virtual_host = Keyword.get(opts, :virtual_host, false) + virtual_host = Keyword.get(opts, :virtual_host, config[:virtual_host] || false) s3_accelerate = Keyword.get(opts, :s3_accelerate, false) - bucket_as_host = Keyword.get(opts, :bucket_as_host, false) + bucket_as_host = Keyword.get(opts, :bucket_as_host, config[:bucket_as_host] || false) {:ok, datetime} = DateTime.now("Etc/UTC") expiration_date = DateTime.add(datetime, expires_in, :second) datetime = datetime_to_erlang_time(datetime) diff --git a/test/lib/s3_test.exs b/test/lib/s3_test.exs index 7a1d701..4c32ef5 100644 --- a/test/lib/s3_test.exs +++ b/test/lib/s3_test.exs @@ -491,6 +491,46 @@ defmodule ExAws.S3Test do assert_pre_signed_url(url, "https://bucket.custom-domain.com/foo.txt", "3600") end + test "#initiate_multipart_upload returns proper operation structure" do + # Test that the operation structure is created correctly + operation = S3.initiate_multipart_upload("my-bucket.custom-domain.com", "test-key.txt") + + assert operation.http_method == :post + assert operation.bucket == "my-bucket.custom-domain.com" + assert operation.path == "test-key.txt" + assert operation.resource == "uploads" + end + + test "#presigned_url with bucket_as_host should not duplicate bucket in path" do + # Test the specific issue where bucket domain appears twice + config = config() + opts = [virtual_host: true, bucket_as_host: true] + + {:ok, url} = S3.presigned_url(config, :get, "my-custom-domain.com", "path/to/file.txt", opts) + + # Should not contain the bucket name in the path when bucket_as_host is true + refute String.contains?(url, "/my-custom-domain.com/path/to/file.txt") + # Should contain the correct path + assert String.contains?(url, "/path/to/file.txt") + # Should use the bucket as the hostname + assert String.starts_with?(url, "https://my-custom-domain.com/") + end + + test "#presigned_url reads bucket_as_host and virtual_host from config" do + # Test that config values are used when options are not provided + config = config() |> Map.put(:virtual_host, true) |> Map.put(:bucket_as_host, true) + + {:ok, url} = S3.presigned_url(config, :get, "my-custom-domain.com", "path/to/file.txt") + + # Should use bucket as hostname even without explicit opts + assert String.starts_with?(url, "https://my-custom-domain.com/") + # Should not duplicate bucket name in path + refute String.contains?(url, "/my-custom-domain.com/path") + # Should contain the correct path + assert String.contains?(url, "/path/to/file.txt") + end + + test "#presigned_url passing query_params option" do query_params = [ key_one: "value_one",