fix(webhook): fix ipv6 in ip and hostname

This commit is contained in:
zhouzb 2021-01-15 18:35:24 +08:00 committed by turtleDeng
parent 114bf8e048
commit 9f0dbeff29
2 changed files with 40 additions and 31 deletions

View File

@ -332,21 +332,31 @@ str(Atom) when is_atom(Atom) -> atom_to_list(Atom);
str(Bin) when is_binary(Bin) -> binary_to_list(Bin). str(Bin) when is_binary(Bin) -> binary_to_list(Bin).
pool_opts(Params = #{<<"url">> := URL}) -> pool_opts(Params = #{<<"url">> := URL}) ->
#{host := Host, #{host := Host0,
scheme := Scheme} = URIMap = uri_string:parse(URL), scheme := Scheme} = URIMap = uri_string:parse(binary_to_list(URL)),
Port = maps:get(port, URIMap, case Scheme of Port = maps:get(port, URIMap, case Scheme of
<<"https">> -> 443; <<"https">> -> 443;
_ -> 80 _ -> 80
end), end),
PoolSize = maps:get(<<"pool_size">>, Params, 32), PoolSize = maps:get(<<"pool_size">>, Params, 32),
ConnectTimeout = timer:seconds(maps:get(<<"connect_timeout">>, Params, 5)), ConnectTimeout = timer:seconds(maps:get(<<"connect_timeout">>, Params, 5)),
IPv6 = case inet:getaddr(binary_to_list(Host), inet6) of Host = case inet:parse_address(Host0) of
{ok, {_,_,_,_} = Addr} -> Addr;
{ok, {_,_,_,_,_,_,_,_} = Addr} -> Addr;
{error, einval} -> Host0
end,
Inet = case Host of
{_,_,_,_} -> inet;
{_,_,_,_,_,_,_,_} -> inet6;
_ ->
case inet:getaddr(Host, inet6) of
{error, _} -> inet; {error, _} -> inet;
{ok, _} -> inet6 {ok, _} -> inet6
end
end, end,
MoreOpts = case Scheme of MoreOpts = case Scheme of
<<"http">> -> <<"http">> ->
[{transport_opts, [IPv6]}]; [{transport_opts, [Inet]}];
<<"https">> -> <<"https">> ->
KeyFile = maps:get(<<"keyfile">>, Params), KeyFile = maps:get(<<"keyfile">>, Params),
CertFile = maps:get(<<"certfile">>, Params), CertFile = maps:get(<<"certfile">>, Params),
@ -366,7 +376,7 @@ pool_opts(Params = #{<<"url">> := URL}) ->
{ciphers, lists:foldl(fun(TlsVer, Ciphers) -> {ciphers, lists:foldl(fun(TlsVer, Ciphers) ->
Ciphers ++ ssl:cipher_suites(all, TlsVer) Ciphers ++ ssl:cipher_suites(all, TlsVer)
end, [], TlsVers)} | TLSOpts], end, [], TlsVers)} | TLSOpts],
[{transport, ssl}, {transport_opts, [IPv6 | NTLSOpts]}] [{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
end, end,
[{host, Host}, [{host, Host},
{port, Port}, {port, Port},

View File

@ -40,7 +40,7 @@ stop(_State) ->
ehttpc_sup:stop_pool(?APP). ehttpc_sup:stop_pool(?APP).
add_default_scheme(URL) when is_list(URL) -> add_default_scheme(URL) when is_list(URL) ->
add_default_scheme(list_to_binary(URL)); binary_to_list(add_default_scheme(list_to_binary(URL)));
add_default_scheme(<<"http://", _/binary>> = URL) -> add_default_scheme(<<"http://", _/binary>> = URL) ->
URL; URL;
add_default_scheme(<<"https://", _/binary>> = URL) -> add_default_scheme(<<"https://", _/binary>> = URL) ->
@ -51,19 +51,31 @@ add_default_scheme(URL) ->
translate_env() -> translate_env() ->
{ok, URL} = application:get_env(?APP, url), {ok, URL} = application:get_env(?APP, url),
#{host := Host0, #{host := Host0,
port := Port,
path := Path0, path := Path0,
scheme := Scheme} = uri_string:parse(binary_to_list(add_default_scheme(URL))), scheme := Scheme} = URIMap = uri_string:parse(add_default_scheme(URL)),
Host = get_addr(Host0), Port = maps:get(port, URIMap, case Scheme of
"https" -> 443;
_ -> 80
end),
Path = path(Path0), Path = path(Path0),
PoolSize = application:get_env(?APP, pool_size, 8), Host = case inet:parse_address(Host0) of
IPv6 = case tuple_size(Host) =:= 8 of {ok, {_,_,_,_} = Addr} -> Addr;
true -> [inet6]; {ok, {_,_,_,_,_,_,_,_} = Addr} -> Addr;
false -> [] {error, einval} -> Host0
end, end,
Inet = case Host of
{_,_,_,_} -> inet;
{_,_,_,_,_,_,_,_} -> inet6;
_ ->
case inet:getaddr(Host, inet6) of
{error, _} -> inet;
{ok, _} -> inet6
end
end,
PoolSize = application:get_env(?APP, pool_size, 32),
MoreOpts = case Scheme of MoreOpts = case Scheme of
"http" -> "http" ->
[{transport_opts, IPv6}]; [{transport_opts, [Inet]}];
"https" -> "https" ->
CACertFile = application:get_env(?APP, cacertfile, undefined), CACertFile = application:get_env(?APP, cacertfile, undefined),
CertFile = application:get_env(?APP, certfile, undefined), CertFile = application:get_env(?APP, certfile, undefined),
@ -84,7 +96,7 @@ translate_env() ->
{ciphers, lists:foldl(fun(TlsVer, Ciphers) -> {ciphers, lists:foldl(fun(TlsVer, Ciphers) ->
Ciphers ++ ssl:cipher_suites(all, TlsVer) Ciphers ++ ssl:cipher_suites(all, TlsVer)
end, [], TlsVers)} | TLSOpts], end, [], TlsVers)} | TLSOpts],
[{transport, ssl}, {transport_opts, NTLSOpts ++ IPv6}] [{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}]
end, end,
PoolOpts = [{host, Host}, PoolOpts = [{host, Host},
{port, Port}, {port, Port},
@ -99,19 +111,6 @@ translate_env() ->
NHeaders = set_content_type(Headers), NHeaders = set_content_type(Headers),
application:set_env(?APP, headers, NHeaders). application:set_env(?APP, headers, NHeaders).
get_addr(Hostname) ->
case inet:parse_address(Hostname) of
{ok, {_,_,_,_} = Addr} -> Addr;
{ok, {_,_,_,_,_,_,_,_} = Addr} -> Addr;
{error, einval} ->
case inet:getaddr(Hostname, inet) of
{error, _} ->
{ok, Addr} = inet:getaddr(Hostname, inet6),
Addr;
{ok, Addr} -> Addr
end
end.
path("") -> path("") ->
"/"; "/";
path(Path) -> path(Path) ->