Ported flash clients patch from 2.1.x

This commit is contained in:
Alexey Shchepin 2011-07-08 18:17:05 +03:00
parent 3ccbf1115c
commit 72e3e0e6ad
5 changed files with 101 additions and 12 deletions

View File

@ -393,6 +393,9 @@ Some options that you may be interested in modifying:
\titem{--disable-transient-supervisors}
Disable the use of Erlang/OTP supervision for transient processes.
\titem{--enable-flash-hack}
Enable support for non-standard XML socket clients of Adobe Flash 8 and lower.
\end{description}
\makesubsection{install}{Install}

View File

@ -64,6 +64,11 @@ ifeq (@pam@, pam)
INSTALL_EPAM=install -m 750 $(O_USER) epam $(PBINDIR)
endif
ifeq (@flash_hack@, true)
ERLC_FLAGS+=-DENABLE_FLASH_HACK
CPPFLAGS+=-DENABLE_FLASH_HACK
endif
prefix = @prefix@
exec_prefix = @exec_prefix@
@ -158,7 +163,7 @@ mostlyclean-recursive maintainer-clean-recursive:
@ERLC@ -W $(EFLAGS) $*.erl
$(ERLSHLIBS): %.so: %.c
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) \
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(LIBS) \
$(subst ../,,$(subst .so,.c,$@)) \
$(ERLANG_LIBS) \
$(ERLANG_CFLAGS) \

View File

@ -62,6 +62,15 @@ AC_ARG_ENABLE(roster_gateway_workaround,
esac],[roster_gateway_workaround=false])
AC_SUBST(roster_gateway_workaround)
AC_ARG_ENABLE(flash_hack,
[AC_HELP_STRING([--enable-flash-hack], [support Adobe Flash client XML (default: no)])],
[case "${enableval}" in
yes) flash_hack=true ;;
no) flash_hack=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-flash-hack) ;;
esac],[flash_hack=false])
AC_SUBST(flash_hack)
AC_ARG_ENABLE(mssql,
[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[case "${enableval}" in

View File

@ -32,6 +32,13 @@
-define(CONFIG_PATH, "ejabberd.cfg").
-define(LOG_PATH, "ejabberd.log").
-ifdef(ENABLE_FLASH_HACK).
-define(FLASH_HACK, true).
-else.
-define(FLASH_HACK, false).
-endif.
-define(EJABBERD_URI, "http://www.process-one.net/en/ejabberd/").
-define(S2STIMEOUT, 600000).

View File

@ -114,7 +114,8 @@
ip,
aux_fields = [],
fsm_limit_opts,
lang}).
lang,
flash_connection = false}).
%-define(DBGFSM, true).
@ -151,6 +152,14 @@
"id='~s' from='~s'~s~s>"
).
-define(FLASH_STREAM_HEADER,
"<?xml version='1.0'?>"
"<flash:stream xmlns='jabber:client' "
"xmlns:stream='http://etherx.jabber.org/streams' "
"id='~s' from='~s'~s~s>"
).
-define(NS_FLASH_STREAM, "http://www.jabber.com/streams/flash").
-define(INVALID_NS_ERR, exmpp_stream:error('invalid-namespace')).
-define(INVALID_XML_ERR, exmpp_stream:error('xml-not-well-formed')).
-define(HOST_UNKNOWN_ERR, exmpp_stream:error('host-unknown')).
@ -344,7 +353,8 @@ get_subscribed(FsmRef) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
wait_for_stream({xmlstreamstart, #xmlel{ns = NS, name = Name} = Opening},
StateData) ->
DefaultLang = case ?MYLANG of
undefined ->
"en";
@ -353,11 +363,19 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
end,
Header = exmpp_stream:opening_reply(Opening,
StateData#state.streamid, DefaultLang),
case NS of
?NS_XMPP ->
case {NS, exmpp_xml:is_ns_declared_here(Opening, ?NS_FLASH_STREAM),
?FLASH_HACK,
StateData#state.flash_connection} of
{_, true, true, false} ->
%% Flash client connecting - attention!
%% Some of them don't provide an xmlns:stream attribute -
%% compensate for that.
wait_for_stream({xmlstreamstart, Opening#xmlel{ns = ?NS_XMPP}},
StateData#state{flash_connection = true});
{?NS_XMPP, _, _, _} ->
ServerB = exmpp_stringprep:nameprep(
exmpp_stream:get_receiving_entity(Opening)),
Server = binary_to_list(ServerB),
Server = binary_to_list(ServerB),
case ?IS_MY_HOST(Server) of
true ->
Lang = case exmpp_stream:get_lang(Opening) of
@ -518,11 +536,17 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
send_trailer(StateData),
{stop, normal, StateData}
end;
_ ->
send_header(StateData, ?MYNAME, "", DefaultLang),
send_element(StateData, ?INVALID_NS_ERR),
send_trailer(StateData),
{stop, normal, StateData}
_ ->
case Name of
<<"policy-file-request">> ->
send_text(StateData, flash_policy_string()),
{stop, normal, StateData};
_ ->
send_header(StateData, ?MYNAME, "", DefaultLang),
send_element(StateData, ?INVALID_NS_ERR),
send_trailer(StateData),
{stop, normal, StateData}
end
end;
wait_for_stream(timeout, StateData) ->
@ -1565,8 +1589,15 @@ change_shaper(StateData, JID) ->
send_text(StateData, Text) when StateData#state.xml_socket ->
?DEBUG("Send Text on stream = ~p", [lists:flatten(Text)]),
Text1 =
if ?FLASH_HACK and StateData#state.flash_connection ->
%% send a null byte after each stanza to Flash clients
[Text, 0];
true ->
Text
end,
(StateData#state.sockmod):send_xml(StateData#state.socket,
{xmlstreamraw, Text});
{xmlstreamraw, Text1});
send_text(StateData, Text) ->
?DEBUG("Send XML on stream = ~s", [Text]),
(StateData#state.sockmod):send(StateData#state.socket, Text).
@ -1579,6 +1610,15 @@ send_element(StateData, El) when StateData#state.xml_socket ->
send_element(StateData, El) ->
send_text(StateData, exmpp_stanza:to_iolist(El)).
send_header(StateData,Server, Version, Lang)
when StateData#state.flash_connection ->
Header = io_lib:format(?FLASH_STREAM_HEADER,
[StateData#state.streamid,
Server,
Version,
Lang]),
send_text(StateData, Header);
send_header(StateData, Server, Version, Lang)
when StateData#state.xml_socket ->
VersionAttr =
@ -2361,3 +2401,28 @@ pack_string(String, Pack) ->
none ->
{String, gb_trees:insert(String, String, Pack)}
end.
%% @spec () -> string()
%% @doc Build the content of a Flash policy file.
%% It specifies as domain "*".
%% It specifies as to-ports the ports that serve ejabberd_c2s.
flash_policy_string() ->
Listen = ejabberd_config:get_local_option(listen),
ClientPortsDeep = ["," ++ integer_to_list(Port)
|| {{Port,_,_}, ejabberd_c2s, _Opts} <- Listen],
%% NOTE: The function string:join/2 was introduced in Erlang/OTP R12B-0
%% so it can't be used yet in ejabberd.
ToPortsString = case lists:flatten(ClientPortsDeep) of
[$, | Tail] -> Tail;
_ -> []
end,
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE cross-domain-policy SYSTEM "
"\"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n"
"<cross-domain-policy>\n"
" <allow-access-from domain=\"*\" to-ports=\""
++ ToPortsString ++
"\"/>\n"
"</cross-domain-policy>\n\0".