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

Bugfixes (thanks to Alexey Shchepin)

SVN Revision: 2297
This commit is contained in:
Badlop 2009-06-16 18:26:07 +00:00
parent 5f07b4bf9b
commit 94c3a384b1

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 449 2007-12-18 15:00:10Z alexey $ %%% Id : $Id: ejabberd_http_bind.erl 453 2007-12-20 14:35:04Z alexey $
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
-module(ejabberd_http_bind). -module(ejabberd_http_bind).
@ -74,7 +74,7 @@
-define(MAX_REQUESTS, 2). % number of simultaneous requests -define(MAX_REQUESTS, 2). % number of simultaneous requests
-define(MIN_POLLING, 2000000). % don't poll faster than that or we will -define(MIN_POLLING, 2000000). % don't poll faster than that or we will
% shoot you (time in sec) % shoot you (time in microsec)
-define(MAX_WAIT, 3600). % max num of secs to keep a request on hold -define(MAX_WAIT, 3600). % max num of secs to keep a request on hold
-define(MAX_INACTIVITY, 30000). % msecs to wait before terminating -define(MAX_INACTIVITY, 30000). % msecs to wait before terminating
% idle sessions % idle sessions
@ -110,7 +110,7 @@ controlling_process(_Socket, _Pid) ->
ok. ok.
close({http_bind, FsmRef}) -> close({http_bind, FsmRef}) ->
catch gen_fsm:sync_send_all_state_event(FsmRef, close). catch gen_fsm:sync_send_all_state_event(FsmRef, stop).
sockname(_Socket) -> sockname(_Socket) ->
{ok, {{0, 0, 0, 0}, 0}}. {ok, {{0, 0, 0, 0}, 0}}.
@ -287,6 +287,20 @@ 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
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if
StateData#state.pause > 0 ->
erlang:start_timer(
StateData#state.pause*1000, self(), []);
true ->
erlang:start_timer(
?MAX_INACTIVITY, self(), [])
end,
HTTPReply = case Output of HTTPReply = case Output of
[[]| OutPacket] -> [[]| OutPacket] ->
{ok, OutPacket}; {ok, OutPacket};
@ -304,7 +318,8 @@ handle_sync_event({send, Packet}, _From, StateName, StateData) ->
{reply, Reply, StateName, {reply, Reply, StateName,
StateData#state{output = [], StateData#state{output = [],
http_receiver = undefined, http_receiver = undefined,
wait_timer = undefined}}; wait_timer = undefined,
timer = Timer}};
true -> true ->
Reply = ok, Reply = ok,
{reply, Reply, StateName, StateData#state{output = Output}} {reply, Reply, StateName, StateData#state{output = Output}}
@ -371,8 +386,8 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
end end
end end
end, end,
{_,TSec,TMSec} = now(), {TMegSec, TSec, TMSec} = now(),
TNow = TSec*1000*1000 + TMSec, TNow = (TMegSec * 1000000 + TSec) * 1000000 + TMSec,
LastPoll = if LastPoll = if
Payload == "" -> Payload == "" ->
TNow; TNow;
@ -425,15 +440,20 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
%% ?DEBUG("reqlist: ~p", [ReqList]), %% ?DEBUG("reqlist: ~p", [ReqList]),
%% setup next timer %% setup next timer
cancel_timer(StateData#state.timer), if
if StateData#state.timer /= undefined ->
Pause > 0 -> cancel_timer(StateData#state.timer);
Timer = erlang:start_timer( true ->
ok
end,
Timer = if
Pause > 0 ->
erlang:start_timer(
Pause*1000, self(), []); Pause*1000, self(), []);
true -> true ->
Timer = erlang:start_timer( erlang:start_timer(
?MAX_INACTIVITY, self(), []) ?MAX_INACTIVITY, self(), [])
end, end,
case StateData#state.waiting_input of case StateData#state.waiting_input of
false -> false ->
Input = Payload ++ [StateData#state.input], Input = Payload ++ [StateData#state.input],
@ -490,15 +510,6 @@ handle_sync_event({http_put, Rid, Attrs, Payload, Hold, StreamTo},
handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) -> handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
%% setup timer %% setup timer
cancel_timer(StateData#state.timer),
Timer = if
StateData#state.pause > 0 ->
erlang:start_timer(
StateData#state.pause*1000, self(), []);
true ->
erlang:start_timer(
?MAX_INACTIVITY, self(), [])
end,
if if
StateData#state.http_receiver /= undefined -> StateData#state.http_receiver /= undefined ->
gen_fsm:reply(StateData#state.http_receiver, {ok, empty}); gen_fsm:reply(StateData#state.http_receiver, {ok, empty});
@ -511,8 +522,8 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
true -> true ->
ok ok
end, end,
{_,TSec,TMSec} = now(), {TMegSec, TSec, TMSec} = now(),
TNow = TSec*1000*1000 + TMSec, TNow = (TMegSec * 1000000 + TSec) * 1000000 + TMSec,
if if
(Hold > 0) and (Hold > 0) and
(StateData#state.output == "") and (StateData#state.output == "") and
@ -528,9 +539,23 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
output = Output, output = Output,
http_receiver = From, http_receiver = From,
wait_timer = WaitTimer, wait_timer = WaitTimer,
timer = Timer, timer = undefined,
req_list = ReqList}}; req_list = ReqList}};
(StateData#state.input == "cancel") -> (StateData#state.input == "cancel") ->
if
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if
StateData#state.pause > 0 ->
erlang:start_timer(
StateData#state.pause*1000, self(), []);
true ->
erlang:start_timer(
?MAX_INACTIVITY, self(), [])
end,
Output = StateData#state.output, Output = StateData#state.output,
ReqList = StateData#state.req_list, ReqList = StateData#state.req_list,
Reply = {ok, cancel}, Reply = {ok, cancel},
@ -542,6 +567,20 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
timer = Timer, timer = Timer,
req_list = ReqList}}; req_list = ReqList}};
true -> true ->
if
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if
StateData#state.pause > 0 ->
erlang:start_timer(
StateData#state.pause*1000, self(), []);
true ->
erlang:start_timer(
?MAX_INACTIVITY, self(), [])
end,
case StateData#state.output of case StateData#state.output of
[[]| OutPacket] -> [[]| OutPacket] ->
Reply = {ok, OutPacket}; Reply = {ok, OutPacket};
@ -585,14 +624,29 @@ handle_info({timeout, Timer, _}, _StateName,
?DEBUG("ding dong", []), ?DEBUG("ding dong", []),
{stop, normal, StateData}; {stop, normal, StateData};
handle_info({timeout, Timer, _}, StateName, handle_info({timeout, WaitTimer, _}, StateName,
#state{wait_timer = Timer} = StateData) -> #state{wait_timer = WaitTimer} = StateData) ->
if if
StateData#state.http_receiver /= undefined -> StateData#state.http_receiver /= undefined ->
if
StateData#state.timer /= undefined ->
cancel_timer(StateData#state.timer);
true ->
ok
end,
Timer = if
StateData#state.pause > 0 ->
erlang:start_timer(
StateData#state.pause*1000, self(), []);
true ->
erlang:start_timer(
?MAX_INACTIVITY, self(), [])
end,
gen_fsm:reply(StateData#state.http_receiver, {ok, empty}), gen_fsm:reply(StateData#state.http_receiver, {ok, empty}),
{next_state, StateName, {next_state, StateName,
StateData#state{http_receiver = undefined, StateData#state{http_receiver = undefined,
wait_timer = undefined}}; wait_timer = undefined,
timer = Timer}};
true -> true ->
{next_state, StateName, StateData} {next_state, StateName, StateData}
end; end;
@ -611,6 +665,12 @@ terminate(_Reason, _StateName, StateData) ->
fun() -> fun() ->
mnesia:delete({http_bind, StateData#state.id}) mnesia:delete({http_bind, StateData#state.id})
end), end),
if
StateData#state.http_receiver /= undefined ->
gen_fsm:reply(StateData#state.http_receiver, {ok, terminate});
true ->
ok
end,
case StateData#state.waiting_input of case StateData#state.waiting_input of
false -> false ->
case StateData#state.last_receiver of case StateData#state.last_receiver of
@ -706,6 +766,8 @@ prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold}=Sess,
{200, ?HEADER, "<body type='error' xmlns='"++?NS_HTTP_BIND++"'/>"}; {200, ?HEADER, "<body type='error' xmlns='"++?NS_HTTP_BIND++"'/>"};
{ok, empty} -> {ok, empty} ->
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND++"'/>"}; {200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND++"'/>"};
{ok, terminate} ->
{200, ?HEADER, "<body type='terminate' xmlns='"++?NS_HTTP_BIND++"'/>"};
{ok, OutPacket} -> {ok, OutPacket} ->
?DEBUG("OutPacket: ~s", [OutPacket]), ?DEBUG("OutPacket: ~s", [OutPacket]),
case StreamStart of case StreamStart of