Skip to content

Instantly share code, notes, and snippets.

@miguelff
Created April 29, 2011 08:49
Show Gist options
  • Save miguelff/948064 to your computer and use it in GitHub Desktop.
Save miguelff/948064 to your computer and use it in GitHub Desktop.
%%
%% wait_for_stream/2
%%
wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
?TRACE(undefined, "START: ~p", [Attrs]),
DefaultLang = case ?MYLANG of
undefined -> " xml:lang='en'";
DL -> " xml:lang='" ++ DL ++ "'"
end,
case xml:get_attr_s("xmlns:stream", Attrs) of
?NS_STREAM ->
Server = jlib:nameprep(xml:get_attr_s("to", Attrs)),
case lists:member(Server, ?MYHOSTS) of
true ->
Lang = xml:get_attr_s("xml:lang", Attrs),
change_shaper(StateData, jlib:make_jid("", Server, "")),
case xml:get_attr_s("version", Attrs) of
"1.0" ->
Header = io_lib:format(?STREAM_HEADER,
[StateData#state.streamid,
Server,
" version='1.0'",
DefaultLang]),
send_text(StateData, Header),
case StateData#state.authenticated of
false ->
SASLState =
cyrsasl:server_new(
"jabber", Server, "", [],
fun(U) ->
ejabberd_auth:get_password_with_authmodule(U, Server)
end,
fun(U, P) ->
check_password_with_authmodule(StateData, U, Server, P)
end),
Mechs = lists:map(
fun(S) ->
{xmlelement, "mechanism", [],
[{xmlcdata, S}]}
end, cyrsasl:listmech(Server)),
SockMod =
(StateData#state.sockmod):get_sockmod(
StateData#state.socket),
Zlib = StateData#state.zlib,
CompressFeature =
case Zlib andalso
(SockMod == gen_tcp) of
true ->
[{xmlelement, "compression",
[{"xmlns", ?NS_FEATURE_COMPRESS}],
[{xmlelement, "method",
[], [{xmlcdata, "zlib"}]}]}];
_ ->
[]
end,
send_element(StateData,
{xmlelement, "stream:features", [],
CompressFeature ++
[{xmlelement, "mechanisms",
[{"xmlns", ?NS_SASL}],
Mechs}] ++
ejabberd_hooks:run_fold(
c2s_stream_features,
Server,
[], [])}),
fsm_next_state(wait_for_feature_request,
StateData#state{
server = Server,
sasl_state = SASLState,
lang = Lang});
_ ->
case StateData#state.resource of
"" ->
send_element(
StateData,
{xmlelement, "stream:features", [],
[{xmlelement, "bind",
[{"xmlns", ?NS_BIND}], []},
{xmlelement, "session",
[{"xmlns", ?NS_SESSION}], []}]}),
fsm_next_state(wait_for_bind,
StateData#state{
server = Server,
lang = Lang});
_ ->
send_element(
StateData,
{xmlelement, "stream:features", [], []}),
fsm_next_state(wait_for_session,
StateData#state{
server = Server,
lang = Lang})
end
end;
_ ->
Header = io_lib:format(
?STREAM_HEADER,
[StateData#state.streamid, Server, "",
DefaultLang]),
send_text(StateData, Header),
fsm_next_state(wait_for_auth,
StateData#state{
server = Server,
lang = Lang})
end;
_ ->
Header = io_lib:format(
?STREAM_HEADER,
[StateData#state.streamid, ?MYNAME, "",
DefaultLang]),
send_text(StateData,
Header ++ ?HOST_UNKNOWN_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}
end;
_ ->
Header = io_lib:format(
?STREAM_HEADER,
[StateData#state.streamid, ?MYNAME, "", DefaultLang]),
send_text(StateData,
Header ++ ?INVALID_NS_ERR ++ ?STREAM_TRAILER),
{stop, normal, StateData}
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment