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:
parent
5f07b4bf9b
commit
94c3a384b1
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user