aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Chmielowski <pchmielowski@process-one.net>2012-04-27 13:19:49 +0200
committerPaweł Chmielowski <pchmielowski@process-one.net>2012-04-27 13:23:19 +0200
commit8b13226d00502579960fc196e5b829897f571e09 (patch)
tree3ae7120b67e9608738a86531cc6c7c86751a2206
parentMerge SQL and Mnesia code into one module (EJAB-1560) (diff)
Do not trigger item-not-found errors in mod_http_bind (part of EJABS-1827)
This changes what happens to request received with out of order rid, previously response to such request was send immediately, and client was free to submit another request, which triggered item-not-found if it was delivered before request with missing rid. This change make us wait for sending response to out of order request until request with missing rid arrives. It also queues all outgoing data before that condition is meet.
-rw-r--r--src/web/ejabberd_http_bind.erl22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/web/ejabberd_http_bind.erl b/src/web/ejabberd_http_bind.erl
index b28587fce..0108d4aa1 100644
--- a/src/web/ejabberd_http_bind.erl
+++ b/src/web/ejabberd_http_bind.erl
@@ -66,6 +66,7 @@
last_receiver,
last_poll,
http_receiver,
+ out_of_order_receiver = false,
wait_timer,
ctime = 0,
timer,
@@ -372,6 +373,11 @@ handle_sync_event({send_xml, Packet}, _From, StateName,
Output = [Packet | StateData#state.output],
Reply = ok,
{reply, Reply, StateName, StateData#state{output = Output}};
+handle_sync_event({send_xml, Packet}, _From, StateName,
+ #state{out_of_order_receiver = true} = StateData) ->
+ Output = [Packet | StateData#state.output],
+ Reply = ok,
+ {reply, Reply, StateName, StateData#state{output = Output}};
handle_sync_event({send_xml, Packet}, _From, StateName, StateData) ->
Output = [Packet | StateData#state.output],
cancel_timer(StateData#state.timer),
@@ -440,9 +446,9 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
TNow = tnow(),
if
(Hold > 0) and
- (StateData#state.output == []) and
+ ((StateData#state.output == []) or (StateData#state.rid < Rid)) and
((TNow - StateData#state.ctime) < (Wait*1000*1000)) and
- (StateData#state.rid == Rid) and
+ (StateData#state.rid =< Rid) and
(StateData#state.input /= cancel) and
(StateData#state.pause == 0) ->
WaitTimer = erlang:start_timer(Wait * 1000, self(), []),
@@ -450,6 +456,7 @@ handle_sync_event({http_get, Rid, Wait, Hold}, From, StateName, StateData) ->
cancel_timer(StateData#state.timer),
{next_state, StateName, StateData#state{
http_receiver = From,
+ out_of_order_receiver = StateData#state.rid < Rid,
wait_timer = WaitTimer,
timer = undefined}};
(StateData#state.input == cancel) ->
@@ -587,10 +594,11 @@ handle_http_put_event(#http_put{rid = Rid, attrs = Attrs,
UnprocessedReqList = [Request | Requests],
cancel_timer(StateData#state.timer),
Timer = set_inactivity_timer(0, StateData#state.max_inactivity),
- {reply, buffered, StateName,
- StateData#state{unprocessed_req_list = UnprocessedReqList,
- req_list = ReqList,
- timer = Timer}};
+ {reply, ok, StateName,
+ StateData#state{unprocessed_req_list = UnprocessedReqList,
+ req_list = ReqList,
+ timer = Timer}, hibernate};
+
_ ->
%% Request is in sequence:
process_http_put(Request, StateName, StateData, RidAllow)
@@ -794,8 +802,6 @@ handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize, StreamStart, IP) ->
% {"type", "error"}], []})};
handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize,
StreamStart, IP);
- {buffered, _Sess} ->
- {200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND++"'/>"};
{ok, Sess} ->
prepare_response(Sess, Rid, [], StreamStart)
end.