25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-20 16:15:59 +01:00

Use json module when Erlang/OTP 27, jiffy with older ones

This commit is contained in:
Badlop 2024-05-06 18:02:36 +02:00
parent 0ad1d315e8
commit 696e42b5b4
15 changed files with 84 additions and 54 deletions

View File

@ -46,7 +46,7 @@ defmodule Ejabberd.MixProject do
def application do
[mod: {:ejabberd_app, []},
applications: [:idna, :inets, :kernel, :sasl, :ssl, :stdlib, :mix,
:fast_tls, :fast_xml, :fast_yaml, :jiffy, :jose,
:fast_tls, :fast_xml, :fast_yaml, :jose,
:p1_utils, :stringprep, :syntax_tools, :yconf]
++ cond_apps(),
included_applications: [:mnesia, :os_mon,
@ -114,6 +114,7 @@ defmodule Ejabberd.MixProject do
if_version_below(~c"24", [{:d, :SYSTOOLS_APP_DEF_WITHOUT_OPTIONAL}]) ++
if_version_below(~c"24", [{:d, :OTP_BELOW_24}]) ++
if_version_below(~c"25", [{:d, :OTP_BELOW_25}]) ++
if_version_below(~c"27", [{:d, :OTP_BELOW_27}]) ++
if_type_exported(:odbc, {:opaque, :connection_reference, 0}, [{:d, :ODBC_HAS_TYPES}])
defines = for {:d, value} <- result, do: {:d, value}
result ++ [{:d, :ALL_DEFS, defines}]
@ -139,7 +140,6 @@ defmodule Ejabberd.MixProject do
{:fast_xml, ">= 1.1.51"},
{:fast_yaml, "~> 1.0"},
{:idna, "~> 6.0"},
{:jiffy, "~> 1.1.1"},
{:mqtree, "~> 1.0"},
{:p1_acme, git: "https://github.com/processone/p1_acme", branch: "master"},
{:p1_oauth2, "~> 0.6"},
@ -173,6 +173,7 @@ defmodule Ejabberd.MixProject do
{config(:zlib), {:ezlib, "~> 1.0"}},
{if_version_above(~c"23", true), {:jose, "~> 1.11.10"}},
{if_version_below(~c"24", true), {:jose, "1.11.1"}},
{if_version_below(~c"27", true), {:jiffy, "~> 1.1.1"}},
{if_version_below(~c"22", true), {:lager, "~> 3.9.1"}},
{config(:lua), {:luerl, "~> 1.2.0"}},
{config(:mysql), {:p1_mysql, ">= 1.0.23" }},
@ -185,6 +186,7 @@ defmodule Ejabberd.MixProject do
defp cond_apps do
for {:true, app} <- [{config(:stun), :stun},
{Map.has_key?(System.get_env(), "RELIVE"), :exsync},
{if_version_below(~c"27", true), :jiffy},
{config(:tools), :observer}], do:
app
end

View File

@ -40,9 +40,8 @@
{fast_xml, "~> 1.1.51", {git, "https://github.com/processone/fast_xml", {tag, "1.1.51"}}},
{fast_yaml, "~> 1.0.36", {git, "https://github.com/processone/fast_yaml", {tag, "1.0.36"}}},
{idna, "~> 6.0", {git, "https://github.com/benoitc/erlang-idna", {tag, "6.0.0"}}},
{if_version_above, "19",
{jiffy, "~> 1.1.1", {git, "https://github.com/davisp/jiffy", {tag, "1.1.1"}}},
{jiffy, "1.1.0", {git, "https://github.com/davisp/jiffy", {tag, "1.1.0"}}} % for R19 and below
{if_version_below, "27",
{jiffy, "~> 1.1.1", {git, "https://github.com/davisp/jiffy", {tag, "1.1.1"}}}
},
{if_version_above, "23",
{jose, "~> 1.11.10", {git, "https://github.com/potatosalad/erlang-jose", {tag, "1.11.10"}}},
@ -131,6 +130,7 @@
{if_version_below, "24", {d, 'SYSTOOLS_APP_DEF_WITHOUT_OPTIONAL'}},
{if_version_below, "24", {d, 'OTP_BELOW_24'}},
{if_version_below, "25", {d, 'OTP_BELOW_25'}},
{if_version_below, "27", {d, 'OTP_BELOW_27'}},
{if_var_false, debug, no_debug_info},
{if_var_true, debug, debug_info},
{if_var_true, elixir, {d, 'ELIXIR_ENABLED'}},
@ -206,10 +206,11 @@
{if_version_above, "25",
{plt_extra_apps,
[asn1, odbc, public_key, stdlib, syntax_tools,
idna, jiffy, jose,
idna, jose,
cache_tab, eimp, fast_tls, fast_xml, fast_yaml,
mqtree, p1_acme, p1_oauth2, p1_utils, pkix,
stringprep, xmpp, yconf,
{if_version_below, "27", jiffy},
{if_var_true, pam, epam},
{if_var_true, redis, eredis},
{if_var_true, sip, esip},

View File

@ -374,7 +374,7 @@ format_arg(Arg, {tuple, Elements}) ->
list_to_tuple(format_args(Args, Elements));
format_arg(Arg, Format) ->
S = unicode:characters_to_binary(Arg, utf8),
JSON = jiffy:decode(S, [return_maps]),
JSON = misc:json_decode(S),
mod_http_api:format_arg(JSON, Format).
format_arg2(Arg, Parse)->

View File

@ -755,7 +755,7 @@ json_response(Code, Body) ->
{Code, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>},
{<<"Cache-Control">>, <<"no-store">>},
{<<"Pragma">>, <<"no-cache">>}],
jiffy:encode(Body)}.
misc:json_encode(Body)}.
%% OAauth error are defined in:
%% https://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-5.2

View File

@ -884,7 +884,7 @@ get_commit_details2(Path) ->
end.
parse_details(Body) ->
Contents = jiffy:decode(Body, [return_maps]),
Contents = misc:json_decode(Body),
{ok, Commit} = maps:find(<<"commit">>, Contents),
{ok, Sha} = maps:find(<<"sha">>, Commit),

View File

@ -42,6 +42,7 @@
is_mucsub_message/1, best_match/2, pmap/2, peach/2, format_exception/4,
get_my_ipv4_address/0, get_my_ipv6_address/0, parse_ip_mask/1,
crypto_hmac/3, crypto_hmac/4, uri_parse/1, uri_parse/2, uri_quote/1,
json_encode/1, json_decode/1,
match_ip_mask/3, format_hosts_list/1, format_cycle/1, delete_dir/1,
semver_to_xxyy/1, logical_processors/0, get_mucsub_event_type/1]).
@ -58,6 +59,13 @@
-type re_mp() :: {re_pattern, _, _, _, _}.
-export_type([re_mp/0]).
-ifdef(OTP_BELOW_27).
-type json_value() :: jiffy:json_value().
-else.
-type json_value() :: json:encode_value().
-endif.
-export_type([json_value/0]).
-type distance_cache() :: #{{string(), string()} => non_neg_integer()}.
-spec uri_parse(binary()|string()) -> {ok, string(), string(), string(), number(), string(), string()} | {error, term()}.
@ -122,6 +130,18 @@ crypto_hmac(Type, Key, Data) -> crypto:mac(hmac, Type, Key, Data).
crypto_hmac(Type, Key, Data, MacL) -> crypto:macN(hmac, Type, Key, Data, MacL).
-endif.
-ifdef(OTP_BELOW_27).
json_encode(Term) ->
jiffy:encode(Term).
json_decode(Bin) ->
jiffy:decode(Bin, [return_maps]).
-else.
json_encode(Term) ->
iolist_to_binary(json:encode(Term)).
json_decode(Bin) ->
json:decode(Bin).
-endif.
%%%===================================================================
%%% API
%%%===================================================================

View File

@ -154,14 +154,22 @@ get_type(Hdrs) ->
depends(_Host, _Opts) ->
[].
mod_opt_type(json) ->
-ifdef(OTP_BELOW_27).
mod_opt_type_json() ->
econf:and_then(
econf:bool(),
fun(false) -> false;
(true) ->
ejabberd:start_app(jiffy),
true
end);
end).
-else.
mod_opt_type_json() ->
econf:bool().
-endif.
mod_opt_type(json) ->
mod_opt_type_json();
mod_opt_type(max_concat) ->
econf:pos_int(unlimited);
mod_opt_type(max_inactivity) ->

View File

@ -90,7 +90,7 @@ process([], #request{method = 'GET', host = Host, raw_path = RawPath}) ->
<<"</head>">>,
<<"<body>">>,
<<"<script>">>,
<<"converse.initialize(">>, jiffy:encode(Init4), <<");">>,
<<"converse.initialize(">>, misc:json_encode(Init4), <<");">>,
<<"</script>">>,
<<"</body>">>,
<<"</html>">>]};

View File

@ -125,7 +125,7 @@ file_json(Host) ->
{200, [html,
{<<"Content-Type">>, <<"application/json">>},
{<<"Access-Control-Allow-Origin">>, <<"*">>}],
[jiffy:encode(#{links => BoshList ++ WsList})]}.
[misc:json_encode(#{links => BoshList ++ WsList})]}.
get_url(M, bosh, Tls, Host) ->
get_url(M, Tls, Host, bosh_service_url, mod_bosh);

View File

@ -197,7 +197,7 @@ perform_call(Command, Args, Req, Version) ->
%% Be tolerant to make API more easily usable from command-line pipe.
extract_args(<<"\n">>) -> [];
extract_args(Data) ->
Maps = jiffy:decode(Data, [return_maps]),
Maps = misc:json_decode(Data),
maps:to_list(Maps).
% get API version N from last "vN" element in URL path
@ -492,10 +492,10 @@ invalid_token_response() ->
badrequest_response() ->
badrequest_response(<<"400 Bad Request">>).
badrequest_response(Body) ->
json_response(400, jiffy:encode(Body)).
json_response(400, misc:json_encode(Body)).
json_format({Code, Result}) ->
json_response(Code, jiffy:encode(Result));
json_response(Code, misc:json_encode(Result));
json_format({HTMLCode, JSONErrorCode, Message}) ->
json_error(HTMLCode, JSONErrorCode, Message).
@ -506,8 +506,8 @@ json_response(Code, Body) when is_integer(Code) ->
%% message is binary
json_error(HTTPCode, JSONCode, Message) ->
{HTTPCode, ?HEADER(?CT_JSON),
jiffy:encode(#{<<"status">> => <<"error">>,
<<"code">> => JSONCode,
misc:json_encode(#{<<"status">> => <<"error">>,
<<"code">> => JSONCode,
<<"message">> => Message})
}.

View File

@ -75,13 +75,13 @@ process([<<"key">>, <<"v2">>, <<"server">> | _],
}},
SJSON = sign_json(Host, JSON),
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(SJSON)};
misc:json_encode(SJSON)};
process([<<"federation">>, <<"v1">>, <<"version">>],
#request{method = 'GET', host = _Host} = _Request) ->
JSON = #{<<"server">> => #{<<"name">> => <<"ejabberd/mod_matrix_gw">>,
<<"version">> => <<"0.1">>}},
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(JSON)};
misc:json_encode(JSON)};
process([<<"federation">>, <<"v1">>, <<"query">>, <<"profile">>],
#request{method = 'GET', host = _Host} = Request) ->
case proplists:get_value(<<"user_id">>, Request#request.q) of
@ -116,7 +116,7 @@ process([<<"federation">>, <<"v1">>, <<"user">>, <<"devices">>, UserID],
<<"keys">> => []}],
<<"stream_id">> => 1,
<<"user_id">> => UserID},
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}], jiffy:encode(Res)};
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}], misc:json_encode(Res)};
{result, HTTPResult} ->
HTTPResult
end;
@ -127,7 +127,7 @@ process([<<"federation">>, <<"v1">>, <<"user">>, <<"keys">>, <<"query">>],
DeviceKeys2 = maps:map(fun(_Key, _) -> #{} end, DeviceKeys),
Res = #{<<"device_keys">> => DeviceKeys2},
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{ok, _JSON, _Origin} ->
{400, [], <<"400 Bad Request: invalid format">>};
{result, HTTPResult} ->
@ -156,8 +156,8 @@ process([<<"federation">>, <<"v2">>, <<"invite">>, RoomID, EventID],
?DEBUG("sign event ~p~n", [SEvent]),
ResJSON = #{<<"event">> => SEvent},
mod_matrix_gw_room:join(Host, Origin, RoomID, Sender, UserID),
?DEBUG("res ~s~n", [jiffy:encode(ResJSON)]),
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}], jiffy:encode(ResJSON)};
?DEBUG("res ~s~n", [misc:json_encode(ResJSON)]),
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}], misc:json_encode(ResJSON)};
_ ->
{400, [], <<"400 Bad Request: bad event id">>}
end;
@ -191,7 +191,7 @@ process([<<"federation">>, <<"v1">>, <<"send">>, _TxnID],
end, PDUs),
?DEBUG("send res ~p~n", [Res]),
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(maps:from_list(Res))};
misc:json_encode(maps:from_list(Res))};
{ok, _JSON, _Origin} ->
{400, [], <<"400 Bad Request: invalid format">>};
{result, HTTPResult} ->
@ -212,7 +212,7 @@ process([<<"federation">>, <<"v1">>, <<"get_missing_events">>, RoomID],
?DEBUG("get_missing_events res ~p~n", [PDUs]),
Res = #{<<"events">> => PDUs},
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{ok, _JSON, _Origin} ->
{400, [], <<"400 Bad Request: invalid format">>};
{result, HTTPResult} ->
@ -245,7 +245,7 @@ process([<<"federation">>, <<"v1">>, <<"backfill">>, RoomID],
<<"origin_server_ts">> => erlang:system_time(millisecond),
<<"pdus">> => PDUs},
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{result, HTTPResult} ->
HTTPResult
end;
@ -265,7 +265,7 @@ process([<<"federation">>, <<"v1">>, <<"state_ids">>, RoomID],
<<"pdu_ids">> => PDUs},
?DEBUG("get_state_ids res ~p~n", [Res]),
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{error, room_not_found} ->
{400, [], <<"400 Bad Request: room not found">>};
{error, not_allowed} ->
@ -307,7 +307,7 @@ process([<<"federation">>, <<"v1">>, <<"event">>, EventID],
<<"origin_server_ts">> => erlang:system_time(millisecond),
<<"pdus">> => [PDU]},
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)}
misc:json_encode(Res)}
end;
{result, HTTPResult} ->
HTTPResult
@ -324,27 +324,27 @@ process([<<"federation">>, <<"v1">>, <<"make_join">>, RoomID, UserID],
Res = #{<<"errcode">> => <<"M_NOT_FOUND">>,
<<"error">> => <<"Unknown room">>},
{404, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{error, not_invited} ->
Res = #{<<"errcode">> => <<"M_FORBIDDEN">>,
<<"error">> => <<"You are not invited to this room">>},
{403, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{error, {incompatible_version, Ver}} ->
Res = #{<<"errcode">> => <<"M_INCOMPATIBLE_ROOM_VERSION">>,
<<"error">> => <<"Your homeserver does not support the features required to join this room">>,
<<"room_version">> => Ver},
{400, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{ok, Res} ->
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)}
misc:json_encode(Res)}
end;
_ ->
Res = #{<<"errcode">> => <<"M_FORBIDDEN">>,
<<"error">> => <<"User not from origin">>},
{403, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)}
misc:json_encode(Res)}
end;
{result, HTTPResult} ->
HTTPResult
@ -366,23 +366,23 @@ process([<<"federation">>, <<"v2">>, <<"send_join">>, RoomID, EventID],
Res = #{<<"errcode">> => <<"M_BAD_REQUEST">>,
<<"error">> => Error},
{403, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{ok, Res} ->
?DEBUG("send_join res: ~p~n", [Res]),
{200, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)}
misc:json_encode(Res)}
end;
_ ->
Res = #{<<"errcode">> => <<"M_FORBIDDEN">>,
<<"error">> => <<"User not from origin">>},
{403, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)}
misc:json_encode(Res)}
end;
{ok, _JSON, _Origin} ->
Res = #{<<"errcode">> => <<"M_BAD_REQUEST">>,
<<"error">> => <<"Invalid event format">>},
{400, [{<<"Content-Type">>, <<"application/json;charset=UTF-8">>}],
jiffy:encode(Res)};
misc:json_encode(Res)};
{result, HTTPResult} ->
HTTPResult
end;
@ -409,8 +409,7 @@ preprocess_federation_request(Request, DoSignCheck) ->
if
Request#request.length > 0 ->
try
jiffy:decode(Request2#request.data,
[return_maps])
misc:json_decode(Request2#request.data)
catch
_:_ ->
error
@ -674,7 +673,7 @@ get_pruned_event_id(PrunedEvent) ->
encode_canonical_json(JSON) ->
JSON2 = sort_json(JSON),
jiffy:encode(JSON2).
misc:json_encode(JSON2).
sort_json(#{} = Map) ->
Map2 = maps:map(fun(_K, V) ->
@ -736,7 +735,7 @@ sign_json(Host, JSON) ->
binary(),
[binary()],
[{binary(), binary()}],
none | #{atom() | binary() => jiffy:json_value()},
none | #{atom() | binary() => misc:json_value()},
[any()],
[any()]) -> {ok, any()} | {error, any()}.
@ -772,7 +771,7 @@ send_request(Host, Method, MatrixServer, Path, Query, JSON,
Content =
case JSON of
none -> <<>>;
_ -> jiffy:encode(JSON)
_ -> misc:json_encode(JSON)
end,
Request =
case Method of

View File

@ -67,7 +67,7 @@
sender :: binary(),
prev_events :: [binary()],
origin_server_ts :: integer(),
json :: #{atom() | binary() => jiffy:json_value()},
json :: #{atom() | binary() => misc:json_value()},
state_map}).
-record(data,
@ -510,7 +510,7 @@ handle_event(cast, {join, MatrixServer, RoomID, Sender, UserID}, State, Data) ->
?DEBUG("make_join ~p~n", [MakeJoinRes]),
case MakeJoinRes of
{ok, {{_, 200, _}, _Headers, Body}} ->
try jiffy:decode(Body, [return_maps]) of
try misc:json_decode(Body) of
#{<<"event">> := Event,
<<"room_version">> := SRoomVersion} ->
case binary_to_room_version(SRoomVersion) of
@ -702,7 +702,7 @@ process_send_join_res(MatrixServer, SendJoinRes, RoomVersion, Data) ->
case SendJoinRes of
{ok, {{_, 200, _}, _Headers, Body}} ->
try
case jiffy:decode(Body, [return_maps]) of
case misc:json_decode(Body) of
#{<<"auth_chain">> := JSONAuthChain,
<<"event">> := JSONEvent,
<<"state">> := JSONState} = JSON when is_list(JSONAuthChain),
@ -1585,7 +1585,7 @@ process_pdu(Host, Origin, PDU) ->
process_missing_events_res(Host, Origin, Pid, RoomID, RoomVersion,
{ok, {{_, 200, _}, _Headers, Body}}) ->
try
case jiffy:decode(Body, [return_maps]) of
case misc:json_decode(Body) of
#{<<"events">> := JSONEvents} when is_list(JSONEvents) ->
process_missing_events(Host, Origin, Pid, RoomID, RoomVersion, JSONEvents)
end
@ -1673,7 +1673,7 @@ request_room_state(Host, Origin, _Pid, RoomID, RoomVersion, Event) ->
case Res of
{ok, {{_, 200, _}, _Headers, Body}} ->
try
case jiffy:decode(Body, [return_maps]) of
case misc:json_decode(Body) of
#{<<"auth_chain">> := JSONAuthChain,
<<"pdus">> := JSONState} = _JSON when is_list(JSONAuthChain),
is_list(JSONState) ->
@ -1732,7 +1732,7 @@ request_event(Host, Origin, _Pid, RoomID, RoomVersion, EventID) ->
case Res of
{ok, {{_, 200, _}, _Headers, Body}} ->
try
case jiffy:decode(Body, [return_maps]) of
case misc:json_decode(Body) of
#{<<"pdus">> := [PDU]} ->
Event = json_to_event(PDU, RoomVersion),
case check_event_sig_and_hash(Host, Event) of

View File

@ -342,7 +342,7 @@ handle_event(cast, {key_reply, KeyID, HTTPResult}, State, Data) ->
case HTTPResult of
{{_, 200, _}, _, SJSON} ->
try
JSON = jiffy:decode(SJSON, [return_maps]),
JSON = misc:json_decode(SJSON),
?DEBUG("key ~p~n", [JSON]),
#{<<"verify_keys">> := VerifyKeys} = JSON,
#{KeyID := KeyData} = VerifyKeys,
@ -447,7 +447,7 @@ do_get_matrix_host_port(Data) ->
case HTTPRes of
{ok, {{_, 200, _}, _Headers, Body}} ->
try
case jiffy:decode(Body, [return_maps]) of
case misc:json_decode(Body) of
#{<<"m.server">> := Server} ->
case binary:split(Server, <<":">>) of
[ServerAddr] ->

View File

@ -147,7 +147,7 @@ to_list(V) when is_list(V) ->
V.
encode_json(Content) ->
case catch jiffy:encode(Content) of
case catch misc:json_encode(Content) of
{'EXIT', Reason} ->
{error, {invalid_payload, Content, Reason}};
Encoded ->
@ -157,7 +157,7 @@ encode_json(Content) ->
decode_json(<<>>) -> [];
decode_json(<<" ">>) -> [];
decode_json(<<"\r\n">>) -> [];
decode_json(Data) -> jiffy:decode(Data, [return_maps]).
decode_json(Data) -> misc:json_decode(Data).
custom_headers(Server) ->
case ejabberd_option:ext_api_headers(Server) of

View File

@ -259,7 +259,7 @@ set_room_affiliation(Config) ->
RequestURL = "http://" ++ ServerHost ++ ":" ++ integer_to_list(WebPort) ++ "/api/set_room_affiliation",
Headers = [{"X-Admin", "true"}],
ContentType = "application/json",
Body = jiffy:encode(#{name => RoomName, service => RoomService, jid => jid:encode(PeerJID), affiliation => member}),
Body = misc:json_encode(#{name => RoomName, service => RoomService, jid => jid:encode(PeerJID), affiliation => member}),
{ok, {{_, 200, _}, _, _}} = httpc:request(post, {RequestURL, Headers, ContentType, Body}, [], []),
#message{id = _, from = RoomJID, to = MyJID, sub_els = [