Просмотр исходного кода

feat(emqx_http_lib): try to parse host ip

Zaiming Shi 4 лет назад
Родитель
Сommit
29475eb610
3 измененных файлов с 21 добавлено и 6 удалено
  1. 4 3
      src/emqx_http_lib.erl
  2. 11 2
      src/emqx_misc.erl
  3. 6 1
      test/emqx_http_lib_tests.erl

+ 4 - 3
src/emqx_http_lib.erl

@@ -91,7 +91,7 @@ do_parse(URI) ->
             normalise_parse_result(Map2)
     end.
 
-normalise_parse_result(#{host := _, scheme := Scheme0} = Map) ->
+normalise_parse_result(#{host := Host, scheme := Scheme0} = Map) ->
     Scheme = atom_scheme(Scheme0),
     DefaultPort = case https =:= Scheme of
                       true  -> 443;
@@ -101,7 +101,8 @@ normalise_parse_result(#{host := _, scheme := Scheme0} = Map) ->
                N when is_number(N) -> N;
                _ -> DefaultPort
            end,
-    Map#{ scheme => Scheme
+    Map#{ scheme := Scheme
+        , host := emqx_misc:maybe_parse_ip(Host)
         , port => Port
         }.
 
@@ -157,4 +158,4 @@ integer_to_hexlist(Int) ->
 
 hex2dec(X) when (X>=$0) andalso (X=<$9) -> X-$0;
 hex2dec(X) when (X>=$A) andalso (X=<$F) -> X-$A+10;
-hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.
+hex2dec(X) when (X>=$a) andalso (X=<$f) -> X-$a+10.

+ 11 - 2
src/emqx_misc.erl

@@ -43,6 +43,7 @@
         , now_to_secs/1
         , now_to_ms/1
         , index_of/2
+        , maybe_parse_ip/1
         , ipv6_probe/1
         ]).
 
@@ -51,6 +52,14 @@
         , hexstr2bin/1
         ]).
 
+%% @doc Parse v4 or v6 string format address to tuple.
+%% `Host' itself is returned if it's not an ip string.
+maybe_parse_ip(Host) ->
+    case inet:parse_address(Host) of
+        {ok, Addr} when is_tuple(Addr) -> Addr;
+        {error, einval} -> Host
+    end.
+
 %% @doc Add `ipv6_probe' socket option if it's supported.
 ipv6_probe(Opts) ->
     case persistent_term:get({?MODULE, ipv6_probe_supported}, unknown) of
@@ -65,7 +74,7 @@ ipv6_probe(Opts) ->
     end.
 
 ipv6_probe(false, Opts) -> Opts;
-ipv6_probe(true, Opts) -> [ipv6_probe | Opts].
+ipv6_probe(true, Opts) -> [{ipv6_probe, true} | Opts].
 
 %% @doc Merge options
 -spec(merge_opts(Opts, Opts) -> Opts when Opts :: proplists:proplist()).
@@ -279,6 +288,6 @@ hexchar2int(I) when I >= $a andalso I =< $f -> I - $a + 10.
 -include_lib("eunit/include/eunit.hrl").
 
 ipv6_probe_test() ->
-    ?assertEqual([ipv6_probe], ipv6_probe([])).
+    ?assertEqual([{ipv6_probe, true}], ipv6_probe([])).
 
 -endif.

+ 6 - 1
test/emqx_http_lib_tests.erl

@@ -62,7 +62,7 @@ uri_parse_test_() ->
        end
       }
     , {"normalise",
-       fun() -> ?assertMatch({ok, #{scheme := https}},
+       fun() -> ?assertMatch({ok, #{scheme := https, host := {127, 0, 0, 1}}},
                              emqx_http_lib:uri_parse("HTTPS://127.0.0.1"))
        end
       }
@@ -71,4 +71,9 @@ uri_parse_test_() ->
                              emqx_http_lib:uri_parse("wss://127.0.0.1"))
        end
       }
+    , {"ipv6 host",
+       fun() -> ?assertMatch({ok, #{scheme := http, host := T}} when size(T) =:= 8,
+                             emqx_http_lib:uri_parse("http://[::1]:80"))
+       end
+      }
     ].