From 9f0dbeff29d8bb51e9e09c7d4db1b3ff2bcb9985 Mon Sep 17 00:00:00 2001 From: zhouzb Date: Fri, 15 Jan 2021 18:35:24 +0800 Subject: [PATCH] fix(webhook): fix ipv6 in ip and hostname --- .../src/emqx_web_hook_actions.erl | 24 +++++++--- apps/emqx_web_hook/src/emqx_web_hook_app.erl | 47 +++++++++---------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/apps/emqx_web_hook/src/emqx_web_hook_actions.erl b/apps/emqx_web_hook/src/emqx_web_hook_actions.erl index a02252acd..4c34babcc 100644 --- a/apps/emqx_web_hook/src/emqx_web_hook_actions.erl +++ b/apps/emqx_web_hook/src/emqx_web_hook_actions.erl @@ -332,21 +332,31 @@ str(Atom) when is_atom(Atom) -> atom_to_list(Atom); str(Bin) when is_binary(Bin) -> binary_to_list(Bin). pool_opts(Params = #{<<"url">> := URL}) -> - #{host := Host, - scheme := Scheme} = URIMap = uri_string:parse(URL), + #{host := Host0, + scheme := Scheme} = URIMap = uri_string:parse(binary_to_list(URL)), Port = maps:get(port, URIMap, case Scheme of <<"https">> -> 443; _ -> 80 end), PoolSize = maps:get(<<"pool_size">>, Params, 32), ConnectTimeout = timer:seconds(maps:get(<<"connect_timeout">>, Params, 5)), - IPv6 = case inet:getaddr(binary_to_list(Host), inet6) of - {error, _} -> inet; - {ok, _} -> inet6 + 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; + {ok, _} -> inet6 + end end, MoreOpts = case Scheme of <<"http">> -> - [{transport_opts, [IPv6]}]; + [{transport_opts, [Inet]}]; <<"https">> -> KeyFile = maps:get(<<"keyfile">>, Params), CertFile = maps:get(<<"certfile">>, Params), @@ -366,7 +376,7 @@ pool_opts(Params = #{<<"url">> := URL}) -> {ciphers, lists:foldl(fun(TlsVer, Ciphers) -> Ciphers ++ ssl:cipher_suites(all, TlsVer) end, [], TlsVers)} | TLSOpts], - [{transport, ssl}, {transport_opts, [IPv6 | NTLSOpts]}] + [{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}] end, [{host, Host}, {port, Port}, diff --git a/apps/emqx_web_hook/src/emqx_web_hook_app.erl b/apps/emqx_web_hook/src/emqx_web_hook_app.erl index 218002b2b..2c0697c81 100644 --- a/apps/emqx_web_hook/src/emqx_web_hook_app.erl +++ b/apps/emqx_web_hook/src/emqx_web_hook_app.erl @@ -40,7 +40,7 @@ stop(_State) -> ehttpc_sup:stop_pool(?APP). 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) -> URL; add_default_scheme(<<"https://", _/binary>> = URL) -> @@ -51,19 +51,31 @@ add_default_scheme(URL) -> translate_env() -> {ok, URL} = application:get_env(?APP, url), #{host := Host0, - port := Port, path := Path0, - scheme := Scheme} = uri_string:parse(binary_to_list(add_default_scheme(URL))), - Host = get_addr(Host0), + scheme := Scheme} = URIMap = uri_string:parse(add_default_scheme(URL)), + Port = maps:get(port, URIMap, case Scheme of + "https" -> 443; + _ -> 80 + end), Path = path(Path0), - PoolSize = application:get_env(?APP, pool_size, 8), - IPv6 = case tuple_size(Host) =:= 8 of - true -> [inet6]; - false -> [] - end, + 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; + {ok, _} -> inet6 + end + end, + PoolSize = application:get_env(?APP, pool_size, 32), MoreOpts = case Scheme of "http" -> - [{transport_opts, IPv6}]; + [{transport_opts, [Inet]}]; "https" -> CACertFile = application:get_env(?APP, cacertfile, undefined), CertFile = application:get_env(?APP, certfile, undefined), @@ -84,7 +96,7 @@ translate_env() -> {ciphers, lists:foldl(fun(TlsVer, Ciphers) -> Ciphers ++ ssl:cipher_suites(all, TlsVer) end, [], TlsVers)} | TLSOpts], - [{transport, ssl}, {transport_opts, NTLSOpts ++ IPv6}] + [{transport, ssl}, {transport_opts, [Inet | NTLSOpts]}] end, PoolOpts = [{host, Host}, {port, Port}, @@ -99,19 +111,6 @@ translate_env() -> NHeaders = set_content_type(Headers), 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) ->