浏览代码

Introduce rebar_uri

Attempts to bridge http_uri (deprecated in OTP 23)
and uri_string (available as of OTP 21+).

(cherry picked from commit 7057cbe281)
pull/2195/head
Michael Klishin 5 年前
父节点
当前提交
db842388b4
找不到此签名对应的密钥 GPG 密钥 ID: E80EDCFA0CDB21EE
共有 4 个文件被更改,包括 84 次插入13 次删除
  1. +2
    -2
      src/rebar_git_resource.erl
  2. +44
    -0
      src/rebar_uri.erl
  3. +25
    -8
      src/rebar_utils.erl
  4. +13
    -3
      test/rebar_utils_SUITE.erl

+ 2
- 2
src/rebar_git_resource.erl 查看文件

@ -117,8 +117,8 @@ parse_git_url(Url) ->
end.
parse_git_url(not_scp, Url) ->
UriOpts = [{scheme_defaults, [{git, 9418} | http_uri:scheme_defaults()]}],
case http_uri:parse(Url, UriOpts) of
{ok, {_Scheme, _User, Host, _Port, Path, _Query}} ->
case rebar_uri:parse(Url, UriOpts) of
#{path := Path, host := Host} ->
{ok, {Host, filename:rootname(Path, ".git")}};
{error, Reason} ->
{error, Reason}

+ 44
- 0
src/rebar_uri.erl 查看文件

@ -0,0 +1,44 @@
%%% @doc multi-OTP version compatibility shim for working with URIs
-module(rebar_uri).
-ifdef (OTP_RELEASE).
-export([parse/1]).
-spec parse(URIString) -> URIMap when
URIString :: uri_string:uri_string(),
URIMap :: uri_string:uri_map() | uri_string:error().
parse(URIString) ->
uri_string:parse(URIString).
-else.
-export([parse/1]).
-spec parse(URIString) -> URIMap when
URIString :: iodata(),
URIMap :: map() | {error, atom(), term()}.
parse(URIString) ->
case http_uri:parse(URIString) of
{error, Reason} ->
%% no additional parser/term info available to us,
%% e.g. see what uri_string returns in
%% uri_string:parse(<<"h$ttp:::://////lolz">>).
{error, Reason, ""};
{ok, {Scheme, UserInfo, Host, Port, Path, Query}} ->
#{
scheme => Scheme,
host => Host,
port => Port,
path => Path,
%% http_uri:parse/1 includes the leading question mark
%% in query string but uri_string:parse/1 leaves it out.
%% string:slice/2 isn't available in OTP <= 19.
query => case Query of
[] -> "";
_ -> string:substr(Query, 2)
end,
userinfo => UserInfo
}
end.
-endif.

+ 25
- 8
src/rebar_utils.erl 查看文件

@ -910,8 +910,7 @@ get_http_vars(Scheme) ->
-ifdef (OTP_RELEASE).
-if(?OTP_RELEASE >= 23).
-compile({nowarn_deprecated_function, [{http_uri, parse, 1},
{http_uri, decode, 1}]}).
-compile({nowarn_deprecated_function, [{http_uri, decode, 1}]}).
-endif.
-endif.
@ -924,7 +923,10 @@ set_httpc_options(_, []) ->
set_httpc_options(Scheme, Proxy) ->
URI = normalise_proxy(Scheme, Proxy),
{ok, {_, UserInfo, Host, Port, _, _}} = http_uri:parse(URI),
Parts = rebar_uri:parse(URI),
Host = maps:get(host, Parts, []),
Port = maps:get(port, Parts, []),
UserInfo = maps:get(userinfo, Parts, []),
httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar),
set_proxy_auth(UserInfo).
@ -935,14 +937,30 @@ normalise_proxy(Scheme, URI) ->
_ -> URI
end.
%% OTP 21+
-ifdef (OTP_RELEASE).
url_append_path(Url, ExtraPath) ->
case http_uri:parse(Url) of
{ok, {Scheme, UserInfo, Host, Port, Path, Query}} ->
case rebar_uri:parse(Url) of
#{path := Path} = Map ->
FullPath = filename:join(Path, ExtraPath),
{ok, uri_string:recompose(maps:update(path, FullPath, Map))};
_ ->
error
end.
-else.
url_append_path(Url, ExtraPath) ->
case rebar_uri:parse(Url) of
#{scheme := Scheme, userinfo := UserInfo, host := Host, port := Port, path := Path, query := Query} ->
PrefixedQuery = case Query of
[] -> [];
Other -> lists:append(["?", Other])
end,
{ok, lists:append([atom_to_list(Scheme), "://", UserInfo, Host, ":", integer_to_list(Port),
filename:join(Path, ExtraPath), Query])};
filename:join(Path, ExtraPath), PrefixedQuery])};
_ ->
error
end.
-endif.
%% escape\ as\ a\ shell\?
escape_chars(Str) when is_atom(Str) ->
@ -1028,8 +1046,7 @@ ssl_opts(Url) ->
ssl_opts(ssl_verify_enabled, Url) ->
case check_ssl_version() of
true ->
{ok, {_, _, Hostname, _, _, _}} =
http_uri:parse(rebar_utils:to_list(Url)),
#{host := Hostname} = rebar_uri:parse(rebar_utils:to_list(Url)),
VerifyFun = {fun ssl_verify_hostname:verify_fun/3,
[{check_hostname, Hostname}]},
CACerts = certifi:cacerts(),

+ 13
- 3
test/rebar_utils_SUITE.erl 查看文件

@ -322,6 +322,16 @@ is_list_of_strings(_Config) ->
?assert(rebar_utils:is_list_of_strings("foo") == false).
url_append_path(_Config) ->
?assertEqual({ok, "https://repo.hex.pm:443/repos/org"}, rebar_utils:url_append_path("https://repo.hex.pm", "/repos/org")),
?assertEqual({ok, "https://repo.hex.pm:443/repos/org?foo=bar"}, rebar_utils:url_append_path("https://repo.hex.pm",
"/repos/org?foo=bar")).
%% OTP version differences
{ok, Val1} = rebar_utils:url_append_path("https://repo.hex.pm", "/repos/org"),
?assert(lists:member(Val1, [
"https://repo.hex.pm/repos/org",
"https://repo.hex.pm:443/repos/org"
])),
{ok, Val2} = rebar_utils:url_append_path("https://repo.hex.pm?foo=bar", "/repos/org"),
?assert(lists:member(Val2, [
"https://repo.hex.pm/repos/org?foo=bar",
"https://repo.hex.pm:443/repos/org?foo=bar"
])),
?assertEqual({ok, "https://repo.hex.pm:443/repos/org?foo=bar"},
rebar_utils:url_append_path("https://repo.hex.pm:443?foo=bar", "/repos/org")).

正在加载...
取消
保存