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

Update Hex.Repo to use hex_core to fetch data #993

Merged
Merged
Show file tree
Hide file tree
Changes from 5 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
8 changes: 8 additions & 0 deletions lib/hex/http.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ defmodule Hex.HTTP do
@request_redirects 3
@request_retries 2

@spec config() :: :mix_hex_core.config()
def config do
%{
:mix_hex_core.default_config()
| http_adapter: {__MODULE__, %{}}
}
end

@impl :mix_hex_http
def request(method, url, headers, body, opts \\ []) do
headers =
Expand Down
58 changes: 28 additions & 30 deletions lib/hex/repo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -181,30 +181,39 @@ defmodule Hex.Repo do
defp merge_values(left, _right), do: left

def get_package(repo, package, etag) do
headers = Map.merge(etag_headers(etag), auth_headers(repo))
config =
HTTP.config()
|> put_auth_config(repo)
|> put_etag_config(etag)

HTTP.request(:get, package_url(repo, package), headers, nil)
:mix_hex_repo.get_package(config, package)
|> handle_response()
end

def get_docs(repo, package, version) do
headers = auth_headers(repo)
config =
HTTP.config()
|> put_auth_config(repo)

HTTP.request(:get, docs_url(repo, package, version), headers, nil)
:mix_hex_repo.get_docs(config, package, version)
|> handle_response()
end

def get_tarball(repo, package, version) do
headers = auth_headers(repo)
config =
HTTP.config()
|> put_auth_config(repo)

HTTP.request(:get, tarball_url(repo, package, version), headers, nil)
:mix_hex_repo.get_tarball(config, package, version)
|> handle_response()
end

def get_public_key(repo) do
headers = auth_headers(repo)
config =
HTTP.config()
|> put_auth_config(repo)

HTTP.request(:get, public_key_url(repo), headers, nil)
:mix_hex_repo.get_public_key(config)
cgerling marked this conversation as resolved.
Show resolved Hide resolved
|> handle_response()
end

Expand Down Expand Up @@ -242,38 +251,27 @@ defmodule Hex.Repo do
|> version_latest()
end

defp package_url(repo, package) do
config = get_repo(repo)
config.url <> "/packages/#{URI.encode(package)}"
end

defp docs_url(repo, package, version) do
config = get_repo(repo)
config.url <> "/docs/#{URI.encode(package)}-#{URI.encode(version)}.tar.gz"
end

def tarball_url(repo, package, version) do
config = get_repo(repo)
config.url <> "/tarballs/#{URI.encode(package)}-#{URI.encode(version)}.tar"
end

defp public_key_url(repo), do: repo.url <> "/public_key"
defp put_auth_config(config, repo) when is_binary(repo) or is_nil(repo) do
repo = get_repo(repo)

defp etag_headers(nil), do: %{}
defp etag_headers(etag), do: %{"if-none-match" => etag}
put_auth_config(config, repo)
end

defp auth_headers(repo) when is_binary(repo) or repo == nil do
repo
|> get_repo()
|> auth_headers()
defp put_auth_config(config, %{trusted: true} = repo) do
%{config | repo_key: repo.auth_key, repo_url: repo.url}
end

defp auth_headers(%{trusted: true, auth_key: key}) when is_binary(key) do
%{"authorization" => key}
defp put_auth_config(config, %{trusted: _}) do
config
end

defp auth_headers(%{trusted: _, auth_key: _}) do
%{}
defp put_etag_config(config, etag) do
%{config | http_etag: etag}
end

defp parse_csv(body) do
Expand Down Expand Up @@ -346,7 +344,7 @@ defmodule Hex.Repo do
releases
else
case :mix_hex_registry.decode_package(body, repo, package) do
{:ok, releases} ->
{:ok, %{releases: releases}} ->
outer_checksum? = Enum.all?(releases, &Map.has_key?(&1, :outer_checksum))

if not outer_checksum? and Hex.Server.should_warn_registry_version?() do
Expand Down
8 changes: 5 additions & 3 deletions scripts/vendor_hex_core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,24 @@ filenames="hex_core.hrl \
hex_erl_tar.erl \
hex_erl_tar.hrl \
hex_filename.erl \
hex_http.erl \
hex_http_httpc.erl \
hex_licenses.erl \
hex_pb_names.erl \
hex_pb_package.erl \
hex_pb_signed.erl \
hex_pb_versions.erl \
hex_tarball.erl \
hex_registry.erl \
hex_repo.erl \
hex_http.erl \
hex_http_httpc.erl \
hex_tarball.erl \
safe_erl_term.xrl"

search_to_replace="hex_core: \
hex_core) \
hex_core.hrl \
hex_erl_tar \
hex_filename \
hex_licenses \
hex_pb_names \
hex_pb_package \
hex_pb_signed \
Expand Down
23 changes: 12 additions & 11 deletions src/mix_hex_core.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% @doc
%% `hex_core' entrypoint module.
Expand Down Expand Up @@ -55,16 +55,17 @@
-export_type([config/0]).

%% https://hex.pm/docs/public_keys
-define(HEXPM_PUBLIC_KEY, <<"-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApqREcFDt5vV21JVe2QNB
Edvzk6w36aNFhVGWN5toNJRjRJ6m4hIuG4KaXtDWVLjnvct6MYMfqhC79HAGwyF+
IqR6Q6a5bbFSsImgBJwz1oadoVKD6ZNetAuCIK84cjMrEFRkELtEIPNHblCzUkkM
3rS9+DPlnfG8hBvGi6tvQIuZmXGCxF/73hU0/MyGhbmEjIKRtG6b0sJYKelRLTPW
XgK7s5pESgiwf2YC/2MGDXjAJfpfCd0RpLdvd4eRiXtVlE9qO9bND94E7PgQ/xqZ
J1i2xWFndWa6nfFnRxZmCStCOZWYYPlaxr+FZceFbpMwzTNs4g3d4tLNUcbKAIH4
0wIDAQAB
-----END PUBLIC KEY-----">>).

-define(HEXPM_PUBLIC_KEY, <<
"-----BEGIN PUBLIC KEY-----\n"
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApqREcFDt5vV21JVe2QNB\n"
"Edvzk6w36aNFhVGWN5toNJRjRJ6m4hIuG4KaXtDWVLjnvct6MYMfqhC79HAGwyF+\n"
"IqR6Q6a5bbFSsImgBJwz1oadoVKD6ZNetAuCIK84cjMrEFRkELtEIPNHblCzUkkM\n"
"3rS9+DPlnfG8hBvGi6tvQIuZmXGCxF/73hU0/MyGhbmEjIKRtG6b0sJYKelRLTPW\n"
"XgK7s5pESgiwf2YC/2MGDXjAJfpfCd0RpLdvd4eRiXtVlE9qO9bND94E7PgQ/xqZ\n"
"J1i2xWFndWa6nfFnRxZmCStCOZWYYPlaxr+FZceFbpMwzTNs4g3d4tLNUcbKAIH4\n"
"0wIDAQAB\n"
"-----END PUBLIC KEY-----"
>>).

-type config() :: #{
api_key => binary() | undefined,
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.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

-define(HEX_CORE_VERSION, "0.8.2").
-define(HEX_CORE_VERSION, "0.10.0").
2 changes: 1 addition & 1 deletion src/mix_hex_erl_tar.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% @private
%% Copied from https://github.com/erlang/otp/blob/OTP-20.0.1/lib/stdlib/src/erl_tar.erl
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_erl_tar.hrl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

% Copied from https://github.com/erlang/otp/blob/OTP-20.0.1/lib/stdlib/src/erl_tar.hrl

Expand Down
16 changes: 8 additions & 8 deletions src/mix_hex_filename.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

% @private
% Excerpt from https://github.com/erlang/otp/blob/OTP-20.0.1/lib/stdlib/src/filename.erl#L761-L788
Expand Down Expand Up @@ -39,22 +39,22 @@ safe_relative_path(Path) ->
unsafe
end.

safe_relative_path_1(["."|T], Acc) ->
safe_relative_path_1(["." | T], Acc) ->
safe_relative_path_1(T, Acc);
safe_relative_path_1([<<".">>|T], Acc) ->
safe_relative_path_1([<<".">> | T], Acc) ->
safe_relative_path_1(T, Acc);
safe_relative_path_1([".."|T], Acc) ->
safe_relative_path_1([".." | T], Acc) ->
climb(T, Acc);
safe_relative_path_1([<<"..">>|T], Acc) ->
safe_relative_path_1([<<"..">> | T], Acc) ->
climb(T, Acc);
safe_relative_path_1([H|T], Acc) ->
safe_relative_path_1(T, [H|Acc]);
safe_relative_path_1([H | T], Acc) ->
safe_relative_path_1(T, [H | Acc]);
safe_relative_path_1([], []) ->
[];
safe_relative_path_1([], Acc) ->
filename:join(lists:reverse(Acc)).

climb(_, []) ->
unsafe;
climb(T, [_|Acc]) ->
climb(T, [_ | Acc]) ->
safe_relative_path_1(T, Acc).
29 changes: 16 additions & 13 deletions src/mix_hex_http.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% @doc
%% HTTP contract.
Expand All @@ -18,22 +18,25 @@
-type adapter_config() :: map().

-callback request(method(), URI :: binary(), headers(), body(), adapter_config()) ->
{ok, status(), headers(), binary()} |
{error, term()}.
{ok, status(), headers(), binary()}
| {error, term()}.

-spec request(mix_hex_core:config(), method(), URI :: binary(), headers(), body()) ->
{ok, {status(), headers(), binary()}} | {error, term()}.
request(Config, Method, URI, Headers, Body) when is_binary(URI) and is_map(Headers) ->
{Adapter, AdapterConfig} = case maps:get(http_adapter, Config, {mix_hex_http_httpc, #{}}) of
{Adapter0, AdapterConfig0} ->
{Adapter0, AdapterConfig0};
%% TODO: remove in v0.9
Adapter0 when is_atom(Adapter0) ->
AdapterConfig0 = maps:get(http_adapter_config, Config, #{}),
io:format("[mix_hex_http] setting #{http_adapter => Module, http_adapter_config => Map} "
"is deprecated in favour of #{http_adapter => {Module, Map}}~n"),
{Adapter0, AdapterConfig0}
end,
{Adapter, AdapterConfig} =
case maps:get(http_adapter, Config, {mix_hex_http_httpc, #{}}) of
{Adapter0, AdapterConfig0} ->
{Adapter0, AdapterConfig0};
%% TODO: remove in v0.9
Adapter0 when is_atom(Adapter0) ->
AdapterConfig0 = maps:get(http_adapter_config, Config, #{}),
io:format(
"[mix_hex_http] setting #{http_adapter => Module, http_adapter_config => Map} "
"is deprecated in favour of #{http_adapter => {Module, Map}}~n"
),
{Adapter0, AdapterConfig0}
end,
UserAgentFragment = maps:get(http_user_agent_fragment, Config),
Headers2 = put_new(<<"user-agent">>, user_agent(UserAgentFragment), Headers),
Adapter:request(Method, URI, Headers2, Body, AdapterConfig).
Expand Down
45 changes: 29 additions & 16 deletions src/mix_hex_http_httpc.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% @doc
%% httpc-based implementation of {@link mix_hex_http} contract.
Expand All @@ -25,27 +25,30 @@ request(Method, URI, ReqHeaders, Body, AdapterConfig) when is_binary(URI) ->
HTTPOptions = maps:get(http_options, AdapterConfig, []),

HTTPS =
case URI of
<<"https", _/binary>> -> true;
_ -> false
end,
case URI of
<<"https", _/binary>> -> true;
_ -> false
end,
SSLOpts = proplists:get_value(ssl, HTTPOptions),

if
HTTPS == true andalso SSLOpts == undefined ->
io:format("[mix_hex_http_httpc] using default ssl options which are insecure.~n"
"Configure your adapter with: "
"{mix_hex_http_httpc, #{http_options => [{ssl, SslOpts}]}}~n");
true ->
ok
HTTPS == true andalso SSLOpts == undefined ->
io:format(
"[mix_hex_http_httpc] using default ssl options which are insecure.~n"
"Configure your adapter with: "
"{mix_hex_http_httpc, #{http_options => [{ssl, SslOpts}]}}~n"
);
true ->
ok
end,

Request = build_request(URI, ReqHeaders, Body),
case httpc:request(Method, Request, HTTPOptions, [{body_format, binary}], Profile) of
{ok, {{_, StatusCode, _}, RespHeaders, RespBody}} ->
RespHeaders2 = load_headers(RespHeaders),
{ok, {StatusCode, RespHeaders2, RespBody}};
{error, Reason} -> {error, Reason}
{error, Reason} ->
{error, Reason}
end.

%%====================================================================
Expand All @@ -64,10 +67,20 @@ build_request2(URI, ReqHeaders, {ContentType, Body}) ->

%% @private
dump_headers(Map) ->
maps:fold(fun(K, V, Acc) ->
[{binary_to_list(K), binary_to_list(V)} | Acc] end, [], Map).
maps:fold(
fun(K, V, Acc) ->
[{binary_to_list(K), binary_to_list(V)} | Acc]
end,
[],
Map
).

%% @private
load_headers(List) ->
lists:foldl(fun({K, V}, Acc) ->
maps:put(list_to_binary(K), list_to_binary(V), Acc) end, #{}, List).
lists:foldl(
fun({K, V}, Acc) ->
maps:put(list_to_binary(K), list_to_binary(V), Acc)
end,
#{},
List
).
4 changes: 3 additions & 1 deletion src/mix_hex_licenses.erl
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% @doc
%% Hex Licenses.
%% File generated by spdx.ex. Do not edit manually.

-module(mix_hex_licenses).
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_pb_names.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% -*- coding: utf-8 -*-
%% @private
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_pb_package.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% -*- coding: utf-8 -*-
%% @private
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_pb_signed.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% -*- coding: utf-8 -*-
%% @private
Expand Down
2 changes: 1 addition & 1 deletion src/mix_hex_pb_versions.erl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
%% Vendored from hex_core v0.8.2, do not edit manually
%% Vendored from hex_core v0.10.0 (d87858a), do not edit manually

%% -*- coding: utf-8 -*-
%% @private
Expand Down
Loading