diff --git a/src/ejabberd_option.erl b/src/ejabberd_option.erl index 2a5c36963..d9ded9bdf 100644 --- a/src/ejabberd_option.erl +++ b/src/ejabberd_option.erl @@ -119,6 +119,10 @@ -export([redis_server/0]). -export([registration_timeout/0]). -export([resource_conflict/0, resource_conflict/1]). +-export([rest_proxy/0, rest_proxy/1]). +-export([rest_proxy_password/0, rest_proxy_password/1]). +-export([rest_proxy_port/0, rest_proxy_port/1]). +-export([rest_proxy_username/0, rest_proxy_username/1]). -export([router_cache_life_time/0]). -export([router_cache_missed/0]). -export([router_cache_size/0]). @@ -833,6 +837,34 @@ resource_conflict() -> resource_conflict(Host) -> ejabberd_config:get_option({resource_conflict, Host}). +-spec rest_proxy() -> binary(). +rest_proxy() -> + rest_proxy(global). +-spec rest_proxy(global | binary()) -> binary(). +rest_proxy(Host) -> + ejabberd_config:get_option({rest_proxy, Host}). + +-spec rest_proxy_password() -> string(). +rest_proxy_password() -> + rest_proxy_password(global). +-spec rest_proxy_password(global | binary()) -> string(). +rest_proxy_password(Host) -> + ejabberd_config:get_option({rest_proxy_password, Host}). + +-spec rest_proxy_port() -> char(). +rest_proxy_port() -> + rest_proxy_port(global). +-spec rest_proxy_port(global | binary()) -> char(). +rest_proxy_port(Host) -> + ejabberd_config:get_option({rest_proxy_port, Host}). + +-spec rest_proxy_username() -> string(). +rest_proxy_username() -> + rest_proxy_username(global). +-spec rest_proxy_username(global | binary()) -> string(). +rest_proxy_username(Host) -> + ejabberd_config:get_option({rest_proxy_username, Host}). + -spec router_cache_life_time() -> 'infinity' | pos_integer(). router_cache_life_time() -> ejabberd_config:get_option({router_cache_life_time, global}). diff --git a/src/ejabberd_options.erl b/src/ejabberd_options.erl index 8dc88cd23..489320840 100644 --- a/src/ejabberd_options.erl +++ b/src/ejabberd_options.erl @@ -333,6 +333,14 @@ opt_type(registration_timeout) -> econf:timeout(second, infinity); opt_type(resource_conflict) -> econf:enum([setresource, closeold, closenew, acceptnew]); +opt_type(rest_proxy) -> + econf:domain(); +opt_type(rest_proxy_port) -> + econf:port(); +opt_type(rest_proxy_username) -> + econf:string(); +opt_type(rest_proxy_password) -> + econf:string(); opt_type(router_cache_life_time) -> econf:timeout(second, infinity); opt_type(router_cache_missed) -> @@ -652,6 +660,10 @@ options() -> {redis_server, "localhost"}, {registration_timeout, timer:seconds(600)}, {resource_conflict, acceptnew}, + {rest_proxy, <<>>}, + {rest_proxy_port, 0}, + {rest_proxy_username, ""}, + {rest_proxy_password, ""}, {router_cache_life_time, fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end}, {router_cache_missed, diff --git a/src/ejabberd_options_doc.erl b/src/ejabberd_options_doc.erl index 36bebcd5c..cbbc4be9f 100644 --- a/src/ejabberd_options_doc.erl +++ b/src/ejabberd_options_doc.erl @@ -1194,6 +1194,22 @@ doc() -> "uses old Jabber Non-SASL authentication (XEP-0078), " "then this option is not respected, and the action performed " "is 'closeold'.")}}, + {rest_proxy, + #{value => "Host", + desc => ?T("Address of a HTTP Connect proxy used by modules issuing rest calls " + "(like ejabberd_oauth_rest)")}}, + {rest_proxy_port, + #{value => "1..65535", + desc => ?T("Port of a HTTP Connect proxy used by modules issuing rest calls " + "(like ejabberd_oauth_rest)")}}, + {rest_proxy_username, + #{value => "string()", + desc => ?T("Username used to authenticate to HTTP Connect proxy used by modules issuing rest calls " + "(like ejabberd_oauth_rest)")}}, + {rest_proxy_password, + #{value => "string()", + desc => ?T("Password used to authenticate to HTTP Connect proxy used by modules issuing rest calls " + "(like ejabberd_oauth_rest)")}}, {router_cache_life_time, #{value => "timeout()", desc => diff --git a/src/rest.erl b/src/rest.erl index 7fde9e710..6134c0557 100644 --- a/src/rest.erl +++ b/src/rest.erl @@ -38,7 +38,14 @@ start(Host) -> application:start(inets), Size = ejabberd_option:ext_api_http_pool_size(Host), - httpc:set_options([{max_sessions, Size}]). + Proxy = case {ejabberd_option:rest_proxy(Host), + ejabberd_option:rest_proxy_port(Host)} of + {<<>>, _, _} -> + []; + {Host, Port} -> + [{proxy, {{binary_to_list(Host), Port}, []}}] + end, + httpc:set_options([{max_sessions, Size}] ++ Proxy). stop(_Host) -> ok. @@ -87,8 +94,15 @@ request(Server, Method, Path, Params, Mime, Data) -> _ -> {Params, []} end, URI = to_list(url(Server, Path, Query)), - HttpOpts = [{connect_timeout, ?CONNECT_TIMEOUT}, - {timeout, ?HTTP_TIMEOUT}], + HttpOpts = case {ejabberd_option:rest_proxy_username(Server), + ejabberd_option:rest_proxy_password(Server)} of + {"", _} -> [{connect_timeout, ?CONNECT_TIMEOUT}, + {timeout, ?HTTP_TIMEOUT}]; + {User, Pass} -> + [{connect_timeout, ?CONNECT_TIMEOUT}, + {timeout, ?HTTP_TIMEOUT}, + {proxy_auth, {User, Pass}}] + end, Hdrs = [{"connection", "keep-alive"}, {"Accept", "application/json"}, {"User-Agent", "ejabberd"}]