diff --git a/src/ejabberd_acme.erl b/src/ejabberd_acme.erl index 44d93da2c..74579f549 100644 --- a/src/ejabberd_acme.erl +++ b/src/ejabberd_acme.erl @@ -1220,9 +1220,7 @@ opt_type(acme) -> fun(L) -> lists:map( fun({ca_url, URL}) -> - URL1 = binary_to_list(URL), - {ok, _} = http_uri:parse(URL1), - {ca_url, URL1}; + {ca_url, misc:try_url(URL)}; ({contact, Contact}) -> [<<_, _/binary>>, <<_, _/binary>>] = binary:split(Contact, <<":">>), diff --git a/src/misc.erl b/src/misc.erl index 9f72ebf88..7aaebffc9 100644 --- a/src/misc.erl +++ b/src/misc.erl @@ -35,7 +35,7 @@ now_to_usec/1, usec_to_now/1, encode_pid/1, decode_pid/2, compile_exprs/2, join_atoms/2, try_read_file/1, get_descr/2, css_dir/0, img_dir/0, js_dir/0, msgs_dir/0, sql_dir/0, - read_css/1, read_img/1, read_js/1]). + read_css/1, read_img/1, read_js/1, try_url/1]). %% Deprecated functions -export([decode_base64/1, encode_base64/1]). @@ -219,6 +219,25 @@ try_read_file(Path) -> erlang:error(badarg) end. +%% @doc Checks if the URL is valid HTTP(S) URL and converts its name to binary. +%% Fails with `badarg` otherwise. The function is intended for usage +%% in configuration validators only. +-spec try_url(binary() | string()) -> binary(). +try_url(URL) -> + case http_uri:parse(URL) of + {ok, {Scheme, _, _, _, _, _}} when Scheme /= http, Scheme /= https -> + ?ERROR_MSG("Unsupported URI scheme: ~s", [URL]), + erlang:error(badarg); + {ok, {_, _, Host, _, _, _}} when Host == ""; Host == <<"">> -> + ?ERROR_MSG("Invalid URL: ~s", [URL]), + erlang:error(badarg); + {ok, _} -> + iolist_to_binary(URL); + {error, _} -> + ?ERROR_MSG("Invalid URL: ~s", [URL]), + erlang:error(badarg) + end. + -spec css_dir() -> file:filename(). css_dir() -> get_dir("css"). diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 43a1999e1..65251e056 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -178,18 +178,14 @@ mod_opt_type(dir_mode) -> mod_opt_type(docroot) -> fun iolist_to_binary/1; mod_opt_type(put_url) -> - fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL - end; + fun misc:try_url/1; mod_opt_type(get_url) -> - fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL; - (undefined) -> undefined + fun(undefined) -> undefined; + (URL) -> misc:try_url(URL) end; mod_opt_type(service_url) -> - fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL; - (undefined) -> undefined + fun(undefined) -> undefined; + (URL) -> misc:try_url(URL) end; mod_opt_type(custom_headers) -> fun(Headers) -> diff --git a/src/mod_register.erl b/src/mod_register.erl index 3737ff96b..ea822e339 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -616,7 +616,9 @@ mod_opt_type({welcome_message, subject}) -> mod_opt_type({welcome_message, body}) -> fun iolist_to_binary/1; mod_opt_type(redirect_url) -> - fun iolist_to_binary/1. + fun(<<>>) -> <<>>; + (URL) -> misc:try_url(URL) + end. mod_options(_Host) -> [{access, all},