25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-30 16:36:29 +01:00

Started code clean-up (EJAB-936)(thanks to Michael Remond)

SVN Revision: 2318
This commit is contained in:
Badlop 2009-06-16 18:27:35 +00:00
parent a1b84c6fa3
commit b74cb8828b

View File

@ -4,7 +4,7 @@
%%% Purpose : Implements XMPP over BOSH (XEP-0205) (formerly known as %%% Purpose : Implements XMPP over BOSH (XEP-0205) (formerly known as
%%% HTTP Binding) %%% HTTP Binding)
%%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de> %%% Created : 21 Sep 2005 by Stefan Strigler <steve@zeank.in-berlin.de>
%%% Id : $Id: ejabberd_http_bind.erl 953 2009-05-07 10:40:40Z alexey $ %%% Id : $Id: ejabberd_http_bind.erl 958 2009-05-12 14:43:41Z mremond $
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
-module(ejabberd_http_bind). -module(ejabberd_http_bind).
@ -135,6 +135,7 @@ process_request(Data, IP) ->
{ok, {"", Rid, Attrs, Payload}} -> {ok, {"", Rid, Attrs, Payload}} ->
case xml:get_attr_s("to",Attrs) of case xml:get_attr_s("to",Attrs) of
"" -> "" ->
?ERROR_MSG("Session not created (Improper addressing)", []),
{200, ?HEADER, "<body type='terminate' " {200, ?HEADER, "<body type='terminate' "
"condition='improper-addressing' " "condition='improper-addressing' "
"xmlns='" ++ ?NS_HTTP_BIND ++ "'/>"}; "xmlns='" ++ ?NS_HTTP_BIND ++ "'/>"};
@ -168,14 +169,13 @@ process_request(Data, IP) ->
end, end,
handle_http_put(Sid, Rid, Attrs, Payload2, StreamStart, IP); handle_http_put(Sid, Rid, Attrs, Payload2, StreamStart, IP);
_ -> _ ->
?ERROR_MSG("Received bad request: ~p", [Data]),
{400, ?HEADER, ""} {400, ?HEADER, ""}
end. end.
handle_session_start(Pid, XmppDomain, Sid, Rid, Attrs, Payload, IP) -> handle_session_start(Pid, XmppDomain, Sid, Rid, Attrs, Payload, IP) ->
?DEBUG("got pid: ~p", [Pid]), ?DEBUG("got pid: ~p", [Pid]),
Wait = case Wait = case string:to_integer(xml:get_attr_s("wait",Attrs)) of
string:to_integer(xml:get_attr_s("wait",Attrs))
of
{error, _} -> {error, _} ->
?MAX_WAIT; ?MAX_WAIT;
{CWait, _} -> {CWait, _} ->
@ -186,9 +186,7 @@ handle_session_start(Pid, XmppDomain, Sid, Rid, Attrs, Payload, IP) ->
CWait CWait
end end
end, end,
Hold = case Hold = case string:to_integer(xml:get_attr_s("hold",Attrs)) of
string:to_integer(xml:get_attr_s("hold",Attrs))
of
{error, _} -> {error, _} ->
(?MAX_REQUESTS - 1); (?MAX_REQUESTS - 1);
{CHold, _} -> {CHold, _} ->
@ -308,12 +306,7 @@ handle_sync_event({send, Packet}, _From, StateName, StateData) ->
Output = [StateData#state.output | Packet], Output = [StateData#state.output | Packet],
if if
StateData#state.http_receiver /= undefined -> StateData#state.http_receiver /= undefined ->
if cancel_timer(StateData#state.timer),
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if Timer = if
StateData#state.pause > 0 -> StateData#state.pause > 0 ->
erlang:start_timer( erlang:start_timer(
@ -329,12 +322,7 @@ handle_sync_event({send, Packet}, _From, StateName, StateData) ->
{ok, Output} {ok, Output}
end, end,
gen_fsm:reply(StateData#state.http_receiver, HTTPReply), gen_fsm:reply(StateData#state.http_receiver, HTTPReply),
if cancel_timer(StateData#state.wait_timer),
StateData#state.wait_timer /= undefined ->
cancel_timer(StateData#state.wait_timer);
true ->
ok
end,
Reply = ok, Reply = ok,
{reply, Reply, StateName, {reply, Reply, StateName,
StateData#state{output = [], StateData#state{output = [],
@ -409,12 +397,7 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
true -> true ->
ok ok
end, end,
if cancel_timer(StateData#state.wait_timer),
StateData#state.wait_timer /= undefined ->
cancel_timer(StateData#state.wait_timer);
true ->
ok
end,
{TMegSec, TSec, TMSec} = now(), {TMegSec, TSec, TMSec} = now(),
TNow = (TMegSec * 1000000 + TSec) * 1000000 + TMSec, TNow = (TMegSec * 1000000 + TSec) * 1000000 + TMSec,
if if
@ -430,12 +413,7 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
wait_timer = WaitTimer, wait_timer = WaitTimer,
timer = undefined}}; timer = undefined}};
(StateData#state.input == "cancel") -> (StateData#state.input == "cancel") ->
if cancel_timer(StateData#state.timer),
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if Timer = if
StateData#state.pause > 0 -> StateData#state.pause > 0 ->
erlang:start_timer( erlang:start_timer(
@ -451,12 +429,7 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
wait_timer = undefined, wait_timer = undefined,
timer = Timer}}; timer = Timer}};
true -> true ->
if cancel_timer(StateData#state.timer),
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if Timer = if
StateData#state.pause > 0 -> StateData#state.pause > 0 ->
erlang:start_timer( erlang:start_timer(
@ -508,19 +481,14 @@ code_change(_OldVsn, StateName, StateData, _Extra) ->
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_info({timeout, Timer, _}, _StateName, handle_info({timeout, Timer, _}, _StateName,
#state{timer = Timer} = StateData) -> #state{timer = Timer} = StateData) ->
?DEBUG("ding dong", []), ?DEBUG("Session timeout. Closing the HTTP bind Session.", []),
{stop, normal, StateData}; {stop, normal, StateData};
handle_info({timeout, WaitTimer, _}, StateName, handle_info({timeout, WaitTimer, _}, StateName,
#state{wait_timer = WaitTimer} = StateData) -> #state{wait_timer = WaitTimer} = StateData) ->
if if
StateData#state.http_receiver /= undefined -> StateData#state.http_receiver /= undefined ->
if cancel_timer(StateData#state.timer),
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if Timer = if
StateData#state.pause > 0 -> StateData#state.pause > 0 ->
erlang:start_timer( erlang:start_timer(
@ -655,12 +623,7 @@ process_http_put({http_put, Rid, Attrs, Payload, Hold, StreamTo, IP},
?DEBUG("reqlist: ~p", [ReqList]), ?DEBUG("reqlist: ~p", [ReqList]),
%% setup next timer %% setup next timer
if cancel_timer(StateData#state.timer),
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if Timer = if
Pause > 0 -> Pause > 0 ->
erlang:start_timer( erlang:start_timer(
@ -743,13 +706,13 @@ process_buffered_request(Reply, StateName, StateData) ->
handle_http_put(Sid, Rid, Attrs, Payload, StreamStart, IP) -> handle_http_put(Sid, Rid, Attrs, Payload, StreamStart, IP) ->
case http_put(Sid, Rid, Attrs, Payload, StreamStart, IP) of case http_put(Sid, Rid, Attrs, Payload, StreamStart, IP) of
{error, not_exists} -> {error, not_exists} ->
?DEBUG("no session associated with sid: ~p", [Sid]), ?ERROR_MSG("no session associated with sid: ~p", [Sid]),
{404, ?HEADER, ""}; {404, ?HEADER, ""};
{{error, Reason}, Sess} -> {{error, Reason}, Sess} ->
?ERROR_MSG("Error on HTTP put. Reason: ~p", [Reason]),
handle_http_put_error(Reason, Sess); handle_http_put_error(Reason, Sess);
{{repeat, OutPacket}, Sess} -> {{repeat, OutPacket}, Sess} ->
?DEBUG("http_put said 'repeat!' ...~nOutPacket: ~p", ?DEBUG("http_put said 'repeat!' ...~nOutPacket: ~p", [OutPacket]),
[OutPacket]),
send_outpacket(Sess, OutPacket); send_outpacket(Sess, OutPacket);
{ok, Sess} -> {ok, Sess} ->
prepare_response(Sess, Rid, Attrs, StreamStart) prepare_response(Sess, Rid, Attrs, StreamStart)
@ -802,17 +765,19 @@ handle_http_put_error(Reason, #http_bind{pid=FsmRef}) ->
gen_fsm:sync_send_all_state_event(FsmRef,stop), gen_fsm:sync_send_all_state_event(FsmRef,stop),
case Reason of case Reason of
not_exists -> %% bad rid not_exists -> %% bad rid
?ERROR_MSG("Closing HTTP bind session (Bad rid).", []),
{404, ?HEADER, ""}; {404, ?HEADER, ""};
bad_key -> bad_key ->
?ERROR_MSG("Closing HTTP bind session (Bad key).", []),
{404, ?HEADER, ""}; {404, ?HEADER, ""};
polling_too_frequently -> polling_too_frequently ->
?ERROR_MSG("Closing HTTP bind session (User polling too frequently).", []),
{403, ?HEADER, ""} {403, ?HEADER, ""}
end. end.
prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess, prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess,
Rid, _, StreamStart) -> Rid, _, StreamStart) ->
receive after 100 -> ok end, receive after 100 -> ok end, %% TODO: Why is this needed. Argh. Bad programming practice.
case catch http_get(Sess, Rid) of case catch http_get(Sess, Rid) of
{ok, cancel} -> {ok, cancel} ->
%% actually it would be better if we could completely %% actually it would be better if we could completely
@ -1013,8 +978,7 @@ send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
end. end.
parse_request(Data) -> parse_request(Data) ->
?DEBUG("--- incoming data --- ~n~s~n --- END --- ", ?DEBUG("--- incoming data --- ~n~s~n --- END --- ", [Data]),
[Data]),
case xml_stream:parse_element(Data) of case xml_stream:parse_element(Data) of
El when element(1, El) == xmlelement -> El when element(1, El) == xmlelement ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, Name, Attrs, Els} = El,
@ -1029,6 +993,7 @@ parse_request(Data) ->
{'EXIT', _} -> {'EXIT', _} ->
{error, bad_request}; {error, bad_request};
Rid -> Rid ->
%% I guess this is to remove XMLCDATA:
FixedEls = FixedEls =
lists:filter( lists:filter(
fun(I) -> fun(I) ->
@ -1039,19 +1004,21 @@ parse_request(Data) ->
false false
end end
end, Els), end, Els),
lists:map( %% MR: I commented this code, because it is not used.
fun(E) -> %% lists:map(
EXmlns = xml:get_tag_attr_s("xmlns",E), %% fun(E) ->
if %% EXmlns = xml:get_tag_attr_s("xmlns",E),
EXmlns == ?NS_CLIENT -> %% if
remove_tag_attr("xmlns",E); %% EXmlns == ?NS_CLIENT ->
true -> %% remove_tag_attr("xmlns",E);
ok %% true ->
end %% ok
end, FixedEls), %% end
Payload = [xml:element_to_string(E) || %% end, FixedEls),
E <- FixedEls], Payload = [xml:element_to_string(E) || E <- FixedEls],
Sid = xml:get_attr_s("sid",Attrs), Sid = xml:get_attr_s("sid",Attrs),
%% MR: I do not think we need to extract
%% Sid. We should have it somewhere else:
{ok, {Sid, Rid, Attrs, Payload}} {ok, {Sid, Rid, Attrs, Payload}}
end end
end; end;
@ -1059,6 +1026,9 @@ parse_request(Data) ->
{error, bad_request} {error, bad_request}
end. end.
%% Cancel timer and empty message queue.
cancel_timer(undefined) ->
ok;
cancel_timer(Timer) -> cancel_timer(Timer) ->
erlang:cancel_timer(Timer), erlang:cancel_timer(Timer),
receive receive
@ -1068,6 +1038,7 @@ cancel_timer(Timer) ->
ok ok
end. end.
%% TODO: Use tail recursion and list reverse ?
elements_to_string([]) -> elements_to_string([]) ->
[]; [];
elements_to_string([El | Els]) -> elements_to_string([El | Els]) ->
@ -1085,24 +1056,20 @@ get_max_inactivity({Host, _}, Default) ->
get_max_inactivity(_, Default) -> get_max_inactivity(_, Default) ->
Default. Default.
remove_tag_attr(Attr, El) -> remove_tag_attr(Attr, {xmlelement, Name, Attrs, Els}) ->
case El of
{xmlelement, Name, Attrs, Els} ->
Attrs1 = lists:keydelete(Attr, 1, Attrs), Attrs1 = lists:keydelete(Attr, 1, Attrs),
{xmlelement, Name, Attrs1, Els}; {xmlelement, Name, Attrs1, Els};
_ -> remove_tag_attr(Attr, El) ->
El El.
end.
check_default_xmlns({xmlelement, Name, Attrs, Els} = El) -> check_default_xmlns({xmlelement, Name, Attrs, Els} = El) ->
EXmlns = xml:get_tag_attr_s("xmlns", El), case xml:get_tag_attr_s("xmlns", El) of
if "" -> {xmlelement, Name, [{"xmlns", ?NS_CLIENT} | Attrs], Els};
EXmlns == "" -> _ -> El
{xmlelement, Name, [{"xmlns", ?NS_CLIENT} | Attrs], Els};
true ->
El
end. end.
%% Check that mod_http_bind has been defined in config file.
%% Print a warning in log file if this is not the case.
check_bind_module(XmppDomain) -> check_bind_module(XmppDomain) ->
case gen_mod:is_loaded(XmppDomain, mod_http_bind) of case gen_mod:is_loaded(XmppDomain, mod_http_bind) of
true -> ok; true -> ok;