Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExAws.Request.Url.normalize_path/1 breaks operations on S3 objects with slashes at start of key name #546

Open
MisterToolbox opened this issue Mar 23, 2018 · 0 comments

Comments

@MisterToolbox
Copy link

MisterToolbox commented Mar 23, 2018

The function that normalizes paths for AWS operations will cause operations on S3 objects with a / as their first character to fail.

Environment

  • Elixir & Erlang versions (elixir --version):
Erlang/OTP 20 [erts-9.2.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Elixir 1.6.1 (compiled with OTP 20)
  • ExAws version:
mix deps | grep ex_aws
* ex_aws 2.0.2 (Hex package) (mix)
  locked at 2.0.2 (ex_aws) 8df2f96f
* ex_aws_s3 2.0.0 (Hex package) (mix)
  locked at 2.0.0 (ex_aws_s3) 404e7951
  • HTTP client version:
mix deps | grep hackney
* hackney 1.11.0 (Hex package) (rebar3)
  locked at 1.11.0 (hackney) 4951ee01

Current behavior

I've got a bucket that a third-party technology populated with objects whose keys begin with a /:

(I've added two debug logs to the normalize_path/1 function to see the URL before and after it transforms it)

object = ExAws.S3.list_objects(bucket_name)
    |> ExAws.stream!(connection_list)
    |> Enum.take(2) 
    |> List.first

10:00:36.915 [debug] url before normalization: /mybucket//

10:00:36.915 [debug] url after normalization: /mybucket/

10:00:36.947 [debug] Request URL: "https://myendpoint/mybucket/"
...
%{
  e_tag: "\"b0c2828fe6695df01c30df818c443cc8\"",
  key: "/example/container/1234/12345",
  last_modified: "2018-01-26T17:08:27.064Z",
  owner: %{display_name: "example", id: "9ef748b4-b30e-7472-1190-5352fc03bf50"},
  size: "104448",
  storage_class: "STANDARD"
}

If I attempt to head one of these objects, it returns a 404 because the extra slash at the beginning of the object key is stripped off by normalize_path/1

ExAws.S3.head_object(bucket_name, object)
    |> ExAws.request(connection_list)

10:00:41.666 [debug] url before normalization: /mybucket//example/container/1234/12345

10:00:41.666 [debug] url after normalization: /mybucket/example/container/1234/12345

10:00:41.666 [debug] Request URL: "https://myendpoint/mybucket/example/container/1234/12345"
...
10:00:41.666 [debug] Request BODY: ""
{:error,
 {:http_error, 404,
  %{
    headers: [...],
    status_code: 404
  }}}

Workaround

Changing the normalize_path/1 function defp to:

  defp normalize_path(url) do
    url |> Map.update(:path, "", &String.replace(&1, ~r/\/{2,}$/, "/"))
  end

This allows bucket listing (which needs the trailing / stripped) to continue to work and also allows objects with and without the prepended / on the key to be operated on.

Note

I'm near certain that I'm blind to a use case that requires stripping a number of slashes out of it, else this would have been a PR. Thought I'd kick off a dialog and see what shakes out.

Thanks for all the work you've done on ex_aws!

@MisterToolbox MisterToolbox changed the title ExAws.Request.Url.normalize_path/1 breaks operations on S3 objects with multiple slashes in key name ExAws.Request.Url.normalize_path/1 breaks operations on S3 objects with slashes at start of key name Mar 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant