aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_c2s.erl
diff options
context:
space:
mode:
authorHolger Weiss <holger@zedat.fu-berlin.de>2016-02-19 18:53:28 +0100
committerHolger Weiss <holger@zedat.fu-berlin.de>2016-02-19 18:53:28 +0100
commit5b4aefbacd260d86e8e78a7d6680106383869783 (patch)
treecab1466a4d92c742c7987bea1dcddcda6d009b3d /src/ejabberd_c2s.erl
parentAdd Redis backend to the test suite (diff)
Accept stream compression request after SASL
This is an updated version of the patch submitted to EJAB-1382 by Alexey (thanks!).
Diffstat (limited to 'src/ejabberd_c2s.erl')
-rw-r--r--src/ejabberd_c2s.erl99
1 files changed, 66 insertions, 33 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index b9f9d815d..469350ba5 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -469,6 +469,22 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
false ->
[]
end,
+ SockMod =
+ (StateData#state.sockmod):get_sockmod(
+ StateData#state.socket),
+ Zlib = StateData#state.zlib,
+ CompressFeature =
+ case Zlib andalso
+ ((SockMod == gen_tcp) orelse (SockMod == fast_tls)) of
+ true ->
+ [#xmlel{name = <<"compression">>,
+ attrs = [{<<"xmlns">>, ?NS_FEATURE_COMPRESS}],
+ children = [#xmlel{name = <<"method">>,
+ attrs = [],
+ children = [{xmlcdata, <<"zlib">>}]}]}];
+ _ ->
+ []
+ end,
StreamFeatures1 = [#xmlel{name = <<"bind">>,
attrs = [{<<"xmlns">>, ?NS_BIND}],
children = []},
@@ -479,6 +495,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
++
RosterVersioningFeature ++
StreamManagementFeature ++
+ CompressFeature ++
ejabberd_hooks:run_fold(c2s_post_auth_features,
Server, [], [Server]),
StreamFeatures = ejabberd_hooks:run_fold(c2s_stream_features,
@@ -815,38 +832,7 @@ wait_for_feature_request({xmlstreamelement, El},
{?NS_COMPRESS, <<"compress">>}
when Zlib == true,
(SockMod == gen_tcp) or (SockMod == fast_tls) ->
- case fxml:get_subtag(El, <<"method">>) of
- false ->
- send_element(StateData,
- #xmlel{name = <<"failure">>,
- attrs = [{<<"xmlns">>, ?NS_COMPRESS}],
- children =
- [#xmlel{name = <<"setup-failed">>,
- attrs = [], children = []}]}),
- fsm_next_state(wait_for_feature_request, StateData);
- Method ->
- case fxml:get_tag_cdata(Method) of
- <<"zlib">> ->
- Socket = StateData#state.socket,
- BCompressed = fxml:element_to_binary(#xmlel{name = <<"compressed">>,
- attrs = [{<<"xmlns">>, ?NS_COMPRESS}]}),
- ZlibSocket = (StateData#state.sockmod):compress(Socket,
- BCompressed),
- fsm_next_state(wait_for_stream,
- StateData#state{socket = ZlibSocket,
- streamid = new_id()});
- _ ->
- send_element(StateData,
- #xmlel{name = <<"failure">>,
- attrs = [{<<"xmlns">>, ?NS_COMPRESS}],
- children =
- [#xmlel{name =
- <<"unsupported-method">>,
- attrs = [],
- children = []}]}),
- fsm_next_state(wait_for_feature_request, StateData)
- end
- end;
+ process_compression_request(El, wait_for_feature_request, StateData);
_ ->
if TLSRequired and not TLSEnabled ->
Lang = StateData#state.lang,
@@ -1089,7 +1075,19 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
end
end
end;
- _ -> fsm_next_state(wait_for_bind, StateData)
+ _ ->
+ #xmlel{name = Name, attrs = Attrs, children = _Els} = El,
+ Zlib = StateData#state.zlib,
+ SockMod =
+ (StateData#state.sockmod):get_sockmod(StateData#state.socket),
+ case {fxml:get_attr_s(<<"xmlns">>, Attrs), Name} of
+ {?NS_COMPRESS, <<"compress">>}
+ when Zlib == true,
+ (SockMod == gen_tcp) or (SockMod == fast_tls) ->
+ process_compression_request(El, wait_for_bind, StateData);
+ _ ->
+ fsm_next_state(wait_for_bind, StateData)
+ end
end;
wait_for_bind(timeout, StateData) ->
{stop, normal, StateData};
@@ -2510,6 +2508,41 @@ bounce_messages() ->
after 0 -> ok
end.
+process_compression_request(El, StateName, StateData) ->
+ case fxml:get_subtag(El, <<"method">>) of
+ false ->
+ send_element(StateData,
+ #xmlel{name = <<"failure">>,
+ attrs = [{<<"xmlns">>, ?NS_COMPRESS}],
+ children =
+ [#xmlel{name = <<"setup-failed">>,
+ attrs = [], children = []}]}),
+ fsm_next_state(StateName, StateData);
+ Method ->
+ case fxml:get_tag_cdata(Method) of
+ <<"zlib">> ->
+ Socket = StateData#state.socket,
+ BCompressed = fxml:element_to_binary(
+ #xmlel{name = <<"compressed">>,
+ attrs = [{<<"xmlns">>,
+ ?NS_COMPRESS}]}),
+ ZlibSocket = (StateData#state.sockmod):compress(
+ Socket, BCompressed),
+ fsm_next_state(wait_for_stream,
+ StateData#state{socket = ZlibSocket,
+ streamid = new_id()});
+ _ ->
+ send_element(StateData,
+ #xmlel{name = <<"failure">>,
+ attrs = [{<<"xmlns">>, ?NS_COMPRESS}],
+ children =
+ [#xmlel{name = <<"unsupported-method">>,
+ attrs = [],
+ children = []}]}),
+ fsm_next_state(StateName, StateData)
+ end
+ end.
+
%%%----------------------------------------------------------------------
%%% XEP-0191
%%%----------------------------------------------------------------------