diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2016-12-01 11:47:24 -0500 |
---|---|---|
committer | Fred Hebert <mononcqc@ferd.ca> | 2016-12-01 11:47:24 -0500 |
commit | 5f0658d8ac031e5bb7c591eda55a596b021e9c4f (patch) | |
tree | d75303ab4cbe65ebea9ee3ec7d40b0a84be72fda | |
parent | 1766bc30783894f0343e72c4170b709e28741360 (diff) | |
parent | 2c155ead23abeedb39ff761e4db5269f7b2a78ca (diff) |
Merge branch 'artempervin-master'
-rwxr-xr-x | bootstrap | 30 | ||||
-rw-r--r-- | src/rebar3.erl | 3 | ||||
-rw-r--r-- | src/rebar_pkg_resource.erl | 4 | ||||
-rw-r--r-- | src/rebar_utils.erl | 24 | ||||
-rw-r--r-- | test/rebar_utils_SUITE.erl | 42 |
5 files changed, 91 insertions, 12 deletions
@@ -99,8 +99,9 @@ fetch({pkg, Name, Vsn}, App) -> {ok, Binary} -> {ok, Contents} = extract(Binary), ok = erl_tar:extract({binary, Contents}, [{cwd, Dir}, compressed]); - _ -> - io:format("Error: Unable to fetch package ~p ~p~n", [Name, Vsn]) + {error, {Reason, _}} -> + ReasonText = re:replace(atom_to_list(Reason), "_", " ", [global,{return,list}]), + io:format("Error: Unable to fetch package ~s ~s: ~s~n", [Name, Vsn, ReasonText]) end; true -> io:format("Dependency ~s already exists~n", [Name]) @@ -112,8 +113,10 @@ extract(Binary) -> {ok, Contents}. request(Url) -> + HttpOptions = [{relaxed, true} | get_proxy_auth()], + case httpc:request(get, {Url, []}, - [{relaxed, true}], + HttpOptions, [{body_format, binary}], rebar) of {ok, {{_Version, 200, _Reason}, _Headers, Body}} -> @@ -147,8 +150,9 @@ set_httpc_options(_, []) -> ok; set_httpc_options(Scheme, Proxy) -> - {ok, {_, _, Host, Port, _, _}} = http_uri:parse(Proxy), - httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar). + {ok, {_, UserInfo, Host, Port, _, _}} = http_uri:parse(Proxy), + httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar), + set_proxy_auth(UserInfo). compile(App, FirstFiles) -> Dir = filename:join(filename:absname("_build/default/lib/"), App), @@ -402,3 +406,19 @@ otp_release1(Rel) -> binary:bin_to_list(Vsn, {0, Size - 1}) end end. + +set_proxy_auth([]) -> + ok; +set_proxy_auth(UserInfo) -> + Idx = string:chr(UserInfo, $:), + Username = string:sub_string(UserInfo, 1, Idx-1), + Password = string:sub_string(UserInfo, Idx+1), + %% password may contain url encoded characters, need to decode them first + put(proxy_auth, [{proxy_auth, {Username, http_uri:decode(Password)}}]). + +get_proxy_auth() -> + case get(proxy_auth) of + undefined -> []; + ProxyAuth -> ProxyAuth + end. + diff --git a/src/rebar3.erl b/src/rebar3.erl index 4e7e284..1059904 100644 --- a/src/rebar3.erl +++ b/src/rebar3.erl @@ -145,6 +145,8 @@ run_aux(State, RawArgs) -> rebar_core:init_command(rebar_state:command_args(State10, Args), Task). init_config() -> + rebar_utils:set_httpc_options(), + %% Initialize logging system Verbosity = log_level(), ok = rebar_log:init(command_line, Verbosity), @@ -320,7 +322,6 @@ ensure_running(App, Caller) -> end. state_from_global_config(Config, GlobalConfigFile) -> - rebar_utils:set_httpc_options(), GlobalConfigTerms = rebar_config:consult_file(GlobalConfigFile), GlobalConfig = rebar_state:new(GlobalConfigTerms), diff --git a/src/rebar_pkg_resource.erl b/src/rebar_pkg_resource.erl index 5817817..8e1713d 100644 --- a/src/rebar_pkg_resource.erl +++ b/src/rebar_pkg_resource.erl @@ -107,8 +107,10 @@ make_vsn(_) -> {error, "Replacing version of type pkg not supported."}. request(Url, ETag) -> + HttpOptions = [{ssl, ssl_opts(Url)}, {relaxed, true} | rebar_utils:get_proxy_auth()], + case httpc:request(get, {Url, [{"if-none-match", ETag} || ETag =/= false]++[{"User-Agent", rebar_utils:user_agent()}]}, - [{ssl, ssl_opts(Url)}, {relaxed, true}], + HttpOptions, [{body_format, binary}], rebar) of {ok, {{_Version, 200, _Reason}, Headers, Body}} -> diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index f55f40f..a0a44d1 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -70,7 +70,9 @@ info_useless/2, list_dir/1, user_agent/0, - reread_config/1]). + reread_config/1, + get_proxy_auth/0]). + %% for internal use only -export([otp_release/0]). @@ -825,8 +827,9 @@ set_httpc_options(_, []) -> ok; set_httpc_options(Scheme, Proxy) -> - {ok, {_, _, Host, Port, _, _}} = http_uri:parse(Proxy), - httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar). + {ok, {_, UserInfo, Host, Port, _, _}} = http_uri:parse(Proxy), + httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar), + set_proxy_auth(UserInfo). url_append_path(Url, ExtraPath) -> case http_uri:parse(Url) of @@ -865,3 +868,18 @@ list_dir(Dir) -> true -> file:list_dir_all(Dir); false -> file:list_dir(Dir) end. + +set_proxy_auth([]) -> + ok; +set_proxy_auth(UserInfo) -> + Idx = string:chr(UserInfo, $:), + Username = string:sub_string(UserInfo, 1, Idx-1), + Password = string:sub_string(UserInfo, Idx+1), + %% password may contain url encoded characters, need to decode them first + application:set_env(rebar, proxy_auth, [{proxy_auth, {Username, http_uri:decode(Password)}}]). + +get_proxy_auth() -> + case application:get_env(rebar, proxy_auth) of + undefined -> []; + {ok, ProxyAuth} -> ProxyAuth + end. diff --git a/test/rebar_utils_SUITE.erl b/test/rebar_utils_SUITE.erl index b32992d..8b8769b 100644 --- a/test/rebar_utils_SUITE.erl +++ b/test/rebar_utils_SUITE.erl @@ -31,7 +31,8 @@ nonblacklisted_otp_version/1, blacklisted_otp_version/1, sh_does_not_miss_messages/1, - tup_merge/1]). + tup_merge/1, + proxy_auth/1]). -include_lib("common_test/include/ct.hrl"). -include_lib("eunit/include/eunit.hrl"). @@ -46,7 +47,8 @@ end_per_testcase(_, _Config) -> all() -> [{group, args_to_tasks}, sh_does_not_miss_messages, - tup_merge]. + tup_merge, + proxy_auth]. groups() -> [{args_to_tasks, [], [empty_arglist, @@ -272,3 +274,39 @@ tup_merge(_Config) -> rebar_utils:tup_sort([{a,a},{a,a,a},a,{b,a,a},b,{z,a},{z,a,a},{b,a},z]) ) ). + +proxy_auth(_Config) -> + proxy_auth(_Config, "http_proxy"), + proxy_auth(_Config, "https_proxy"). + +proxy_auth(_Config, ProxyEnvKey) -> + Host = "host:", + Port = "1234", + + %% remember current proxy specification + OldProxySpec = os:getenv(ProxyEnvKey), + + %% proxy auth not set + application:unset_env(rebar, proxy_auth), + ?assertEqual([], rebar_utils:get_proxy_auth()), + + %% proxy auth with regular username/password + os:putenv(ProxyEnvKey, "http://Username:Password@" ++ Host ++ Port), + rebar_utils:set_httpc_options(), + ?assertEqual([{proxy_auth, {"Username", "Password"}}], + rebar_utils:get_proxy_auth()), + + %% proxy auth with username missing and url encoded password + os:putenv(ProxyEnvKey, "http://:%3F!abc%23%24@" ++ Host ++ Port), + rebar_utils:set_httpc_options(), + ?assertEqual([{proxy_auth, {"", "?!abc#$"}}], + rebar_utils:get_proxy_auth()), + + %% restore original proxy specification if any + restore_proxy_env(ProxyEnvKey, OldProxySpec), + application:unset_env(rebar, proxy_auth). + +restore_proxy_env(ProxyEnvKey, false) -> + os:putenv(ProxyEnvKey, ""); +restore_proxy_env(ProxyEnvKey, ProxySpec) -> + os:putenv(ProxyEnvKey, ProxySpec). |