diff --git a/apps/emqx/rebar.config b/apps/emqx/rebar.config index e782f714e..c1756b911 100644 --- a/apps/emqx/rebar.config +++ b/apps/emqx/rebar.config @@ -30,6 +30,7 @@ {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.14.4"}}}, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "2.8.1"}}}, {hocon, {git, "https://github.com/emqx/hocon.git", {tag, "0.37.0"}}}, + {emqx_http_lib, {git, "https://github.com/emqx/emqx_http_lib.git", {tag, "0.5.2"}}}, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}}, {recon, {git, "https://github.com/ferd/recon", {tag, "2.5.1"}}}, {snabbkaffe, {git, "https://github.com/kafka4beam/snabbkaffe.git", {tag, "1.0.0"}}} diff --git a/apps/emqx/src/emqx_schema.erl b/apps/emqx/src/emqx_schema.erl index 6412711a6..275a9592e 100644 --- a/apps/emqx/src/emqx_schema.erl +++ b/apps/emqx/src/emqx_schema.erl @@ -43,6 +43,7 @@ -type cipher() :: map(). -type port_number() :: 1..65536. -type server_parse_option() :: #{default_port => port_number(), no_port => boolean()}. +-type url() :: binary(). -typerefl_from_string({duration/0, emqx_schema, to_duration}). -typerefl_from_string({duration_s/0, emqx_schema, to_duration_s}). @@ -56,6 +57,7 @@ -typerefl_from_string({ip_port/0, emqx_schema, to_ip_port}). -typerefl_from_string({cipher/0, emqx_schema, to_erl_cipher_suite}). -typerefl_from_string({comma_separated_atoms/0, emqx_schema, to_comma_separated_atoms}). +-typerefl_from_string({url/0, emqx_schema, to_url}). -export([ validate_heap_size/1, @@ -81,7 +83,8 @@ to_bar_separated_list/1, to_ip_port/1, to_erl_cipher_suite/1, - to_comma_separated_atoms/1 + to_comma_separated_atoms/1, + to_url/1 ]). -export([ @@ -108,7 +111,8 @@ bar_separated_list/0, ip_port/0, cipher/0, - comma_separated_atoms/0 + comma_separated_atoms/0, + url/0 ]). -export([namespace/0, roots/0, roots/1, fields/1, desc/1, tags/0]). @@ -1306,16 +1310,9 @@ fields("ocsp") -> )}, {"responder_url", sc( - binary(), + url(), #{ required => false, - validator => fun ocsp_responder_url_validator/1, - converter => fun - (undefined, _Opts) -> - undefined; - (URL, _Opts) -> - uri_string:normalize(URL) - end, desc => ?DESC("server_ssl_opts_schema_ocsp_responder_url") } )}, @@ -2508,6 +2505,15 @@ to_comma_separated_binary(Str) -> to_comma_separated_atoms(Str) -> {ok, lists:map(fun to_atom/1, string:tokens(Str, ", "))}. +to_url(Str) -> + case emqx_http_lib:uri_parse(Str) of + {ok, URIMap} -> + URIString = emqx_http_lib:normalize(URIMap), + {ok, iolist_to_binary(URIString)}; + Error -> + Error + end. + to_bar_separated_list(Str) -> {ok, string:tokens(Str, "| ")}. diff --git a/apps/emqx/test/emqx_schema_tests.erl b/apps/emqx/test/emqx_schema_tests.erl index a0d264662..5176f4fad 100644 --- a/apps/emqx/test/emqx_schema_tests.erl +++ b/apps/emqx/test/emqx_schema_tests.erl @@ -473,3 +473,43 @@ password_converter_test() -> ?assertEqual(<<"123">>, emqx_schema:password_converter(<<"123">>, #{})), ?assertThrow("must_quote", emqx_schema:password_converter(foobar, #{})), ok. + +url_type_test_() -> + [ + ?_assertEqual( + {ok, <<"http://some.server/">>}, + typerefl:from_string(emqx_schema:url(), <<"http://some.server/">>) + ), + ?_assertEqual( + {ok, <<"http://192.168.0.1/">>}, + typerefl:from_string(emqx_schema:url(), <<"http://192.168.0.1">>) + ), + ?_assertEqual( + {ok, <<"http://some.server/">>}, + typerefl:from_string(emqx_schema:url(), "http://some.server/") + ), + ?_assertEqual( + {ok, <<"http://some.server/">>}, + typerefl:from_string(emqx_schema:url(), <<"http://some.server">>) + ), + ?_assertEqual( + {ok, <<"http://some.server:9090/">>}, + typerefl:from_string(emqx_schema:url(), <<"http://some.server:9090">>) + ), + ?_assertEqual( + {ok, <<"https://some.server:9090/">>}, + typerefl:from_string(emqx_schema:url(), <<"https://some.server:9090">>) + ), + ?_assertEqual( + {ok, <<"https://some.server:9090/path?q=uery">>}, + typerefl:from_string(emqx_schema:url(), <<"https://some.server:9090/path?q=uery">>) + ), + ?_assertEqual( + {error, {unsupported_scheme, <<"postgres">>}}, + typerefl:from_string(emqx_schema:url(), <<"postgres://some.server:9090">>) + ), + ?_assertEqual( + {error, empty_host_not_allowed}, + typerefl:from_string(emqx_schema:url(), <<"">>) + ) + ].