Codebase list erlang-p1-xmpp / 25393d2
New upstream version 1.6.1 Philipp Huebner 1 year, 3 months ago
33 changed file(s) with 172 addition(s) and 57 deletion(s). Raw diff Collapse all Expand all
0 # Version 1.6.1
1
2 * Apply change introduced in XEP-0060 Version 1.23.0
3 * Use net:getaddrinfo for hostname resolution
4
05 # Version 1.6.0
16
27 * Updating fast_tls to version 1.1.16.
55 %%% Created : 10 Jul 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
00 %%%----------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
55 %%% Created : 10 Dec 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
22 %%% Author : Evgeniy Khramtsov <ekhramtsov@process-one.net>
33 %%% Purpose : Rebar build script. Compliant with rebar and rebar3.
44 %%%
5 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
5 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
66 %%%
77 %%% Licensed under the Apache License, Version 2.0 (the "License");
88 %%% you may not use this file except in compliance with the License.
2020
2121 {erl_opts, [debug_info, {src_dirs, ["asn1", "src"]},
2222 nowarn_export_all,
23 {platform_define, "^(R|1|20|21|22)", 'USE_OLD_CRYPTO_HMAC'},
23 {platform_define, "^(R|1|2[012])", 'USE_OLD_CRYPTO_HMAC'},
24 {platform_define, "^(R|1|2[01])", 'USE_GETHOSTBYNAME'},
25 {platform_define, "^(R|1|2[0123]|24\.[012])", 'USE_ADDRPORTCONNECT'},
2426 {i, "include"}]}.
2527
2628 {port_env, [{"ERL_LDFLAGS", " -L$ERL_EI_LIBDIR -lei"},
33 %%% Purpose : Rebar build script. Compliant with rebar and rebar3.
44 %%% Created : 24 Nov 2015 by Mickael Remond <mremond@process-one.net>
55 %%%
6 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
6 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
77 %%%
88 %%% Licensed under the Apache License, Version 2.0 (the "License");
99 %%% you may not use this file except in compliance with the License.
3030 label='The name of the node'/>
3131 <field var='pubsub#type'
3232 type='text-single'
33 label='Payload type'/>
33 label='Payload semantic type information'/>
3434 <field var='pubsub#max_items'
3535 type='text-single'
3636 label='Maximum number of items to persist'/>
177177 label='A friendly name for the node'/>
178178 <field var='pubsub#type'
179179 type='text-single'
180 label='The type of node data, usually specified by
181 the namespace of the payload (if any)'/>
180 label='The semantic type information of data in the node, usually specified
181 by the namespace of the payload (if any)'/>
182182 </form_type>
183183
184184 <!--
55 %%% Created : 24 Nov 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
855855 #xdata_field{var = <<"pubsub#type">>, values = Values,
856856 required = IsRequired, type = 'text-single',
857857 options = Opts, desc = <<>>,
858 label = xmpp_tr:tr(Lang, ?T("Payload type"))}.
858 label =
859 xmpp_tr:tr(Lang,
860 ?T("Payload semantic type information"))}.
859861
860862 -spec encode_max_items(xmpp_util:limit() | undefined,
861863 binary(), boolean()) -> xdata_field().
22132213 options = Opts, desc = <<>>,
22142214 label =
22152215 xmpp_tr:tr(Lang,
2216 ?T("The type of node data, usually specified "
2217 "by the namespace of the payload (if "
2218 "any)"))}.
2216 ?T("The semantic type information of data "
2217 "in the node, usually specified by the "
2218 "namespace of the payload (if any)"))}.
00 %%%-------------------------------------------------------------------
11 %%% @author Stephen Röttger <stephen.roettger@googlemail.com>
22 %%%
3 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
3 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
44 %%%
55 %%% Licensed under the Apache License, Version 2.0 (the "License");
66 %%% you may not use this file except in compliance with the License.
44 %%% @end
55 %%%
66 %%%
7 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
7 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
88 %%%
99 %%% Licensed under the Apache License, Version 2.0 (the "License");
1010 %%% you may not use this file except in compliance with the License.
55 %%% Created : 18 Nov 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
2323
2424 {application, xmpp,
2525 [{description, "Erlang/Elixir XMPP parsing and serialization library"},
26 {vsn, "1.6.0"},
26 {vsn, "1.6.1"},
2727 {modules, []},
2828 {registered, []},
2929 {applications, [kernel, stdlib, ezlib, fast_tls, fast_xml, idna, p1_utils, stringprep]},
55 %%% Created : 9 Dec 2015 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
11 %%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
22 %%%
33 %%%
4 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
4 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
55 %%%
66 %%% Licensed under the Apache License, Version 2.0 (the "License");
77 %%% you may not use this file except in compliance with the License.
55 %%% Created : 30 May 2018 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%% @author Magnus Henoch <henoch@dtek.chalmers.se>
22 %%%
3 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
3 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
44 %%%
55 %%% Licensed under the Apache License, Version 2.0 (the "License");
66 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%% @author Stephen Röttger <stephen.roettger@googlemail.com>
22 %%%
3 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
3 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
44 %%%
55 %%% Licensed under the Apache License, Version 2.0 (the "License");
66 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
121121 connect(Addr, Port, Opts, Timeout, self()).
122122
123123 connect(Addr, Port, Opts, Timeout, Owner) ->
124 case gen_tcp:connect(Addr, Port, Opts, Timeout) of
124 case do_connect(Addr, Port, Opts, Timeout) of
125125 {ok, Socket} ->
126126 SocketData = new(gen_tcp, Socket, []),
127127 case controlling_process(SocketData, Owner) of
135135 {error, _Reason} = Error ->
136136 Error
137137 end.
138
139 -ifndef(USE_ADDRPORTCONNECT).
140 do_connect(Addr, Port, Opts, Timeout)
141 when is_tuple(Addr) orelse
142 is_list(Addr) orelse
143 is_atom(Addr) orelse
144 (Addr =:= any) orelse
145 (Addr =:= loopback) ->
146 gen_tcp:connect(Addr, Port, Opts, Timeout);
147 do_connect(SockAddr, _Port, Opts, Timeout) ->
148 gen_tcp:connect(SockAddr, Opts, Timeout).
149 -else.
150 do_connect(Addr, Port, Opts, Timeout)
151 when is_tuple(Addr) orelse
152 is_list(Addr) orelse
153 is_atom(Addr) orelse
154 (Addr =:= any) orelse
155 (Addr =:= loopback) ->
156 gen_tcp:connect(Addr, Port, Opts, Timeout);
157 do_connect(SockAddr, _Port, Opts, Timeout) ->
158 #{addr := Addr, port := Port} = SockAddr,
159 gen_tcp:connect(Addr, Port, Opts, Timeout).
160 -endif.
138161
139162 -spec starttls(socket_state(), [proplists:property()]) ->
140163 {ok, socket_state()} |
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
8484 -type next_state() :: noreply() | {stop, term(), state()}.
8585 -type host_port() :: {inet:hostname(), inet:port_number(), boolean()} | ip_port().
8686 -type ip_port() :: {inet:ip_address(), inet:port_number(), boolean()}.
87 -type addr_info() :: {net:address_info(), boolean()}.
8788 -type h_addr_list() :: [{{integer(), integer(), inet:port_number(), string()}, boolean()}].
8889 -type network_error() :: {error, inet:posix() | atom()}.
8990 -type tls_error_reason() :: inet:posix() | atom() | binary().
11451146 end
11461147 end.
11471148
1148 -spec resolve(string(), state()) -> {ok, [ip_port()]} | network_error().
1149 -spec resolve(string(), state()) -> {ok, [ip_port()]} | {ok, [addr_info()]} | network_error().
11491150 resolve(Host, State) ->
11501151 try callback(resolve, Host, State) of
11511152 [] ->
11561157 do_resolve(Host, State)
11571158 end.
11581159
1159 -spec do_resolve(string(), state()) -> {ok, [ip_port()]} | network_error().
1160 -spec do_resolve(string(), state()) -> {ok, [ip_port()]} | {ok, [addr_info()]} | network_error().
11601161 do_resolve(Host, State) ->
11611162 case srv_lookup(Host, State) of
11621163 {error, _Reason} ->
12361237 {error, nxdomain}
12371238 end.
12381239
1240
1241 -ifndef(USE_GETHOSTBYNAME).
1242 % New getaddrinfo based lookups (getaddrinfo available in OTP 22, but connect(SockAddr, ...) introduced in OTP 24.3)
1243 -spec a_lookup([host_port()], state()) ->
1244 {ok, [addr_info()]} | network_error().
1245 a_lookup(HostPorts, State) ->
1246 a_lookup(HostPorts, State, [], {error, nxdomain}).
1247
1248 -spec a_lookup([{inet:hostname() | inet:ip_address(), inet:port_number(),
1249 boolean()}],
1250 state(), [addr_info()], network_error()) -> {ok, [addr_info()]} | network_error().
1251 a_lookup([{Addr, Port, TLS}|HostPorts], State, Acc, Err)
1252 when is_tuple(Addr) ->
1253 a_lookup([{inet:ntoa(Addr), Port, TLS}|HostPorts], State, Acc, Err);
1254 a_lookup([{Host, Port, TLS}|HostPorts], State, Acc, Err) ->
1255 Retries = get_dns_retries(State),
1256 case a_lookup(Host, Port, TLS, State, Retries) of
1257 {error, Reason} ->
1258 a_lookup(HostPorts, State, Acc, {error, Reason});
1259 {ok, AddrPorts} ->
1260 a_lookup(HostPorts, State, Acc ++ AddrPorts, Err)
1261 end;
1262 a_lookup([], _State, [], Err) ->
1263 Err;
1264 a_lookup([], _State, Acc, _) ->
1265 {ok, Acc}.
1266
1267 -spec a_lookup(inet:hostname(), inet:port_number(), boolean(),
1268 state(), integer()) -> {ok, [addr_info()]} | network_error().
1269 a_lookup(_Host, _Port, _TLS, _State, Retries) when Retries < 1 ->
1270 {error, timeout};
1271 a_lookup(Host, Port, TLS, State, Retries) ->
1272 Timeout = get_dns_timeout(State),
1273 Start = current_time(),
1274 case net:getaddrinfo(Host, integer_to_list(Port)) of
1275 {error, nxdomain} = Err ->
1276 %% net:getaddrinfo/2 doesn't return {error, timeout},
1277 %% so we should check if 'nxdomain' is in fact a result
1278 %% of a timeout.
1279 End = current_time(),
1280 if (End - Start) >= Timeout ->
1281 a_lookup(Host, Port, TLS, State, Retries - 1);
1282 true ->
1283 Err
1284 end;
1285 {error, _} = Err ->
1286 Err;
1287 {ok, AddressInfos} ->
1288 FilteredAddressInfos = [{Addr, TLSVal} || #{protocol := Protocol} = Addr <- AddressInfos, TLSVal <- [TLS], Protocol == tcp],
1289 {ok, FilteredAddressInfos}
1290 end.
1291
1292 -else.
1293 % Old gethostbyname lookups
12391294 -spec a_lookup([host_port()], state()) ->
12401295 {ok, [ip_port()]} | network_error().
12411296 a_lookup(HostPorts, State) ->
12961351 host_entry_to_addr_ports(HostEntry, Port, TLS)
12971352 end.
12981353
1354 -spec host_entry_to_addr_ports(inet:hostent(), inet:port_number(), boolean()) ->
1355 {ok, [ip_port()]} | {error, nxdomain}.
1356 host_entry_to_addr_ports(#hostent{h_addr_list = AddrList}, Port, TLS) ->
1357 AddrPorts = lists:flatmap(
1358 fun(Addr) ->
1359 try get_addr_type(Addr) of
1360 _ -> [{Addr, Port, TLS}]
1361 catch _:_ ->
1362 []
1363 end
1364 end, AddrList),
1365 case AddrPorts of
1366 [] -> {error, nxdomain};
1367 _ -> {ok, AddrPorts}
1368 end.
1369 -endif.
1370
12991371 -spec h_addr_list_to_host_ports(h_addr_list()) -> {ok, [host_port(),...]} |
13001372 {error, nxdomain}.
13011373 h_addr_list_to_host_ports(AddrList) ->
13161388 _ -> {ok, HostPorts}
13171389 end.
13181390
1319 -spec host_entry_to_addr_ports(inet:hostent(), inet:port_number(), boolean()) ->
1320 {ok, [ip_port()]} | {error, nxdomain}.
1321 host_entry_to_addr_ports(#hostent{h_addr_list = AddrList}, Port, TLS) ->
1322 AddrPorts = lists:flatmap(
1323 fun(Addr) ->
1324 try get_addr_type(Addr) of
1325 _ -> [{Addr, Port, TLS}]
1326 catch _:_ ->
1327 []
1328 end
1329 end, AddrList),
1330 case AddrPorts of
1331 [] -> {error, nxdomain};
1332 _ -> {ok, AddrPorts}
1333 end.
1334
1335 -spec connect([ip_port()], state()) -> {ok, term(), ip_port()} |
1391 -spec connect([ip_port() | addr_info()], state()) -> {ok, term(), ip_port()} |
13361392 {error, {socket, socket_error_reason()}} |
13371393 {error, {tls, tls_error_reason()}}.
13381394 connect(AddrPorts, State) ->
13481404 {error, {socket, Why}}
13491405 end.
13501406
1407 -ifndef(USE_GETHOSTBYNAME).
1408 -spec connect([addr_info()], state(), network_error()) ->
1409 {ok, term(), ip_port()} | network_error().
1410 connect([{#{family := Type, addr := SockAddr}, TLS}|AddressInfos], State, _) ->
1411 #{addr := Addr, port := Port} = SockAddr,
1412 Opts = [binary, {packet, 0},
1413 {send_timeout, ?TCP_SEND_TIMEOUT},
1414 {send_timeout_close, true},
1415 {active, false}, Type],
1416 Opts1 = try callback(connect_options, Addr, Opts, State)
1417 catch _:{?MODULE, undef} -> Opts
1418 end,
1419 Timeout = get_connect_timeout(State),
1420 try xmpp_socket:connect(SockAddr, Port, Opts1, Timeout) of
1421 {ok, Socket} ->
1422 {ok, Socket, {Addr, Port, TLS}};
1423 Err ->
1424 connect(AddressInfos, State, Err)
1425 catch _:badarg ->
1426 connect(AddressInfos, State, {error, einval})
1427 end;
1428 connect([], _State, Err) ->
1429 Err.
1430 -else.
13511431 -spec connect([ip_port()], state(), network_error()) ->
13521432 {ok, term(), ip_port()} | network_error().
13531433 connect([{Addr, Port, TLS}|AddrPorts], State, _) ->
13741454 -spec get_addr_type(inet:ip_address()) -> inet:address_family().
13751455 get_addr_type({_, _, _, _}) -> inet;
13761456 get_addr_type({_, _, _, _, _, _, _, _}) -> inet6.
1457 -endif.
13771458
13781459 -spec get_dns_timeout(state()) -> timeout().
13791460 get_dns_timeout(State) ->
13951476 _:{?MODULE, undef} when NS == ?NS_CLIENT -> 5222
13961477 end.
13971478
1479 -ifdef(USE_GETHOSTBYNAME).
13981480 -spec get_address_families(state()) -> [inet:address_family()].
13991481 get_address_families(State) ->
14001482 try callback(address_families, State)
14011483 catch _:{?MODULE, undef} -> [inet, inet6]
14021484 end.
1485 -endif.
14031486
14041487 -spec get_connect_timeout(state()) -> timeout().
14051488 get_connect_timeout(State) ->
00 %%%-------------------------------------------------------------------
11 %%%
2 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
2 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
33 %%%
44 %%% Licensed under the Apache License, Version 2.0 (the "License");
55 %%% you may not use this file except in compliance with the License.
55 %%% Created : 3 Mar 2018 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
55 %%% Created : 17 Mar 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
55 %%% Created : 27 Nov 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.
55 %%% Created : 12 Jul 2016 by Evgeny Khramtsov <ekhramtsov@process-one.net>
66 %%%
77 %%%
8 %%% Copyright (C) 2002-2022 ProcessOne, SARL. All Rights Reserved.
8 %%% Copyright (C) 2002-2023 ProcessOne, SARL. All Rights Reserved.
99 %%%
1010 %%% Licensed under the Apache License, Version 2.0 (the "License");
1111 %%% you may not use this file except in compliance with the License.