Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 101 additions & 27 deletions lib/hex/http.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,66 @@ defmodule Hex.HTTP do

@impl :mix_hex_http
def request(method, url, headers, body, adapter_config) when is_map(adapter_config) do
{method, url, request, http_opts, timeout, profile} =
prepare_request(method, url, headers, body, adapter_config)

Hex.Shell.debug("Hex.HTTP.request(#{inspect(method)}, #{inspect(url)})")

result =
retry(method, request, http_opts, @request_retries, profile, fn request, http_opts ->
redirect(request, http_opts, @request_redirects, fn request, http_opts ->
timeout(request, http_opts, timeout, fn request, http_opts ->
:httpc.request(method, request, http_opts, [body_format: :binary], profile)
|> handle_response(method, url)
end)
end)
end)

# Convert to hex_core expected format
case result do
{:ok, status, headers, body} ->
# Convert headers to map with binary keys/values for hex_core
headers = Map.new(headers, fn {k, v} -> {to_string(k), to_string(v)} end)
{:ok, {status, headers, body}}

{:error, reason} ->
{:error, reason}
end
end

@impl :mix_hex_http
def request_to_file(method, url, headers, body, filename, adapter_config)
when is_map(adapter_config) do
{method, url, request, http_opts, timeout, profile} =
prepare_request(method, url, headers, body, adapter_config)

Hex.Shell.debug("Hex.HTTP.request_to_file(#{inspect(method)}, #{inspect(url)})")

filename_charlist = String.to_charlist(filename)

result =
retry(method, request, http_opts, @request_retries, profile, fn request, http_opts ->
redirect(request, http_opts, @request_redirects, fn request, http_opts ->
timeout(request, http_opts, timeout, fn request, http_opts ->
:httpc.request(method, request, http_opts, [{:stream, filename_charlist}], profile)
|> handle_response_to_file(method, url)
end)
end)
end)

# Convert to hex_core expected format
case result do
{:ok, status, headers} ->
# Convert headers to map with binary keys/values for hex_core
headers = Map.new(headers, fn {k, v} -> {to_string(k), to_string(v)} end)
{:ok, {status, headers}}

{:error, reason} ->
{:error, reason}
end
end

defp prepare_request(method, url, headers, body, adapter_config) do
# Convert method to atom if it's not already
method = if is_binary(method), do: String.to_atom(method), else: method
# Convert URL to string if it's binary
Expand All @@ -36,8 +96,6 @@ defmodule Hex.HTTP do
# Convert headers from map to our format
headers = if is_map(headers), do: headers, else: Map.new(headers)

Hex.Shell.debug("Hex.HTTP.request(#{inspect(method)}, #{inspect(url)})")

headers = add_basic_auth_via_netrc(headers, url)

timeout =
Expand All @@ -61,30 +119,30 @@ defmodule Hex.HTTP do
end

http_opts = build_http_opts(url, timeout)
opts = [body_format: :binary]
request = build_request(url, headers, body)
profile = Hex.State.fetch!(:httpc_profile)

result =
retry(method, request, http_opts, @request_retries, profile, fn request, http_opts ->
redirect(request, http_opts, @request_redirects, fn request, http_opts ->
timeout(request, http_opts, timeout, fn request, http_opts ->
:httpc.request(method, request, http_opts, opts, profile)
|> handle_response(method, url)
end)
end)
end)
{method, url, request, http_opts, timeout, profile}
end

# Convert to hex_core expected format
case result do
{:ok, status, headers, body} ->
# Convert headers to map with binary keys/values for hex_core
headers = Map.new(headers, fn {k, v} -> {to_string(k), to_string(v)} end)
{:ok, {status, headers, body}}
defp handle_response_to_file({:ok, :saved_to_file}, method, url) do
Hex.Shell.debug("Hex.HTTP.request_to_file(#{inspect(method)}, #{inspect(url)}) => 200")
{:ok, 200, %{}}
end

{:error, reason} ->
{:error, reason}
end
defp handle_response_to_file({:ok, {{_version, code, _reason}, headers, _body}}, method, url) do
Hex.Shell.debug("Hex.HTTP.request_to_file(#{inspect(method)}, #{inspect(url)}) => #{code}")
headers = Map.new(headers, &decode_header/1)
handle_hex_message(headers["x-hex-message"])
{:ok, code, headers}
end

defp handle_response_to_file({:error, term}, method, url) do
Hex.Shell.debug(
"Hex.HTTP.request_to_file(#{inspect(method)}, #{inspect(url)}) => #{inspect(term, limit: :infinity, pretty: true)}"
)

{:error, term}
end

defp fallback(:inet), do: :inet6
Expand Down Expand Up @@ -162,12 +220,7 @@ defmodule Hex.HTTP do
{:ok, code, headers, body} ->
case handle_redirect(code, headers) do
{:ok, location} when times > 0 ->
ssl_opts = Hex.HTTP.SSL.ssl_opts(to_string(location))
http_opts = Keyword.put(http_opts, :ssl, ssl_opts)

request
|> update_request(location)
|> redirect(http_opts, times - 0, fun)
do_redirect(request, http_opts, location, times, fun)

{:ok, _location} ->
Mix.raise("Too many redirects")
Expand All @@ -176,11 +229,32 @@ defmodule Hex.HTTP do
{:ok, code, headers, body}
end

{:ok, code, headers} ->
case handle_redirect(code, headers) do
{:ok, location} when times > 0 ->
do_redirect(request, http_opts, location, times, fun)

{:ok, _location} ->
Mix.raise("Too many redirects")

:error ->
{:ok, code, headers}
end

{:error, reason} ->
{:error, reason}
end
end

defp do_redirect(request, http_opts, location, times, fun) do
ssl_opts = Hex.HTTP.SSL.ssl_opts(to_string(location))
http_opts = Keyword.put(http_opts, :ssl, ssl_opts)

request
|> update_request(location)
|> redirect(http_opts, times - 1, fun)
end

defp handle_redirect(code, headers)
when code in [301, 302, 303, 307, 308] do
if location = headers["location"] do
Expand Down
3 changes: 1 addition & 2 deletions lib/mix/tasks/hex.docs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,7 @@ defmodule Mix.Tasks.Hex.Docs do

defp extract_docs(target, target_dir) do
File.mkdir_p!(target_dir)
fd = File.open!(target, [:read, :compressed])
:ok = :mix_hex_erl_tar.extract({:file, fd}, [:compressed, cwd: Path.dirname(target)])
:ok = :mix_hex_erl_tar.extract(target, [:compressed, cwd: Path.dirname(target)])
Hex.Shell.info("Docs fetched: #{target_dir}")
end

Expand Down
1 change: 0 additions & 1 deletion scripts/vendor_hex_core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ filenames="hex_api_auth.erl \
hex_core.erl \
hex_erl_tar.erl \
hex_erl_tar.hrl \
hex_filename.erl \
hex_http.erl \
hex_http_httpc.erl \
hex_licenses.erl \
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_auth.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Authentication.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_key.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Keys.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_oauth.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - OAuth.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_organization.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Organizations.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_organization_member.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Organization Members.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_package.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Packages.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_package_owner.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Package Owners.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_release.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Releases.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_short_url.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Short URLs.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_api_user.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% Hex HTTP API - Users.
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_core.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

%% @doc
%% `hex_core' entrypoint module.
Expand Down
4 changes: 2 additions & 2 deletions src/mix_hex_core.hrl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
%% Vendored from hex_core v0.12.2 (c4db9f6), do not edit manually
%% Vendored from hex_core v0.15.0 (90f9f59), do not edit manually

-define(HEX_CORE_VERSION, "0.12.2").
-define(HEX_CORE_VERSION, "0.15.0").
Loading
Loading