summaryrefslogtreecommitdiff
path: root/src/web/ejabberd_http_bind.erl
diff options
context:
space:
mode:
authorChristopher tofu Zorn <tofu@stanziq.com>2010-05-05 16:45:46 -0400
committerBadlop <badlop@process-one.net>2010-05-27 21:21:17 +0200
commitd4d45f3a5069158fa18fb96455e36d2f57f941bf (patch)
tree6a6c5c8d2358cc74fd569056fda14e91fcc2403a /src/web/ejabberd_http_bind.erl
parentUpdate the Portuguese Brazil translation (thanks to Otávio Fernandes) (diff)
remove the silly loop that isnt needed, this speeds up all requests by 100 milliseconds. Clean up prepare response function and add two new functions to handle out going payloads based of whether its a new session or not.
Diffstat (limited to 'src/web/ejabberd_http_bind.erl')
-rw-r--r--src/web/ejabberd_http_bind.erl177
1 files changed, 95 insertions, 82 deletions
diff --git a/src/web/ejabberd_http_bind.erl b/src/web/ejabberd_http_bind.erl
index ef3046fe..6f15703e 100644
--- a/src/web/ejabberd_http_bind.erl
+++ b/src/web/ejabberd_http_bind.erl
@@ -102,7 +102,7 @@
-define(MIN_POLLING, 2000000). % don't poll faster than that or we will
% shoot you (time in microsec)
-define(MAX_WAIT, 3600). % max num of secs to keep a request on hold
--define(MAX_INACTIVITY, 120000). % msecs to wait before terminating
+-define(MAX_INACTIVITY, 30000). % msecs to wait before terminating
% idle sessions
-define(MAX_PAUSE, 120). % may num of sec a client is allowed to pause
% the session
@@ -781,7 +781,7 @@ 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, Attrs, StreamStart)
+ prepare_response(Sess, Rid, [], StreamStart)
end.
http_put(Sid, Rid, Attrs, Payload, PayloadSize, StreamStart, IP) ->
@@ -883,9 +883,7 @@ update_shaper(ShaperState, PayloadSize) ->
{NewShaperState, undefined}
end.
-prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess,
- Rid, _, StreamStart) ->
- receive after 100 -> ok end, %% TODO: Why is this needed. Argh. Bad programming practice.
+prepare_response(Sess, Rid, OutputEls, StreamStart) ->
case catch http_get(Sess, Rid) of
{ok, cancel} ->
%% actually it would be better if we could completely
@@ -898,89 +896,104 @@ prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess,
{200, ?HEADER, "<body type='terminate' xmlns='"++?NS_HTTP_BIND++"'/>"};
{ok, ROutPacket} ->
OutPacket = lists:reverse(ROutPacket),
- ?DEBUG("OutPacket: ~p", [OutPacket]),
- case StreamStart of
- false ->
- case catch send_outpacket(Sess, OutPacket) of
- {'EXIT', _Reason} ->
- {200, ?HEADER,
- "<body type='terminate' xmlns='"++
- ?NS_HTTP_BIND++"'/>"};
- SendRes ->
- SendRes
- end;
- true ->
- case OutPacket of
- [{xmlstreamstart, _, OutAttrs} | Els] ->
- AuthID = xml:get_attr_s("id", OutAttrs),
- From = xml:get_attr_s("from", OutAttrs),
- Version = xml:get_attr_s("version", OutAttrs),
- OutEls =
- case Els of
- [] ->
- [];
- [{xmlstreamelement,
- {xmlelement, "stream:features",
- StreamAttribs, StreamEls}}
- | StreamTail] ->
- TypedTail =
- [check_default_xmlns(OEl) ||
- {xmlstreamelement, OEl} <-
- StreamTail],
- [{xmlelement, "stream:features",
- [{"xmlns:stream",
- ?NS_STREAM}] ++
- StreamAttribs, StreamEls}] ++
- TypedTail;
- StreamTail ->
- [check_default_xmlns(OEl) ||
- {xmlstreamelement, OEl} <-
- StreamTail]
- end,
- BOSH_attribs =
- [{"authid", AuthID},
- {"xmlns:xmpp", ?NS_BOSH},
- {"xmlns:stream", ?NS_STREAM}] ++
- case OutEls of
- [] ->
- [];
- _ ->
- [{"xmpp:version", Version}]
- end,
- MaxInactivity = get_max_inactivity(To, ?MAX_INACTIVITY),
- MaxPause = get_max_pause(To),
- {200, ?HEADER,
- xml:element_to_string(
- {xmlelement,"body",
- [{"xmlns",
- ?NS_HTTP_BIND},
- {"sid", Sid},
- {"wait", integer_to_list(Wait)},
- {"requests", integer_to_list(Hold+1)},
- {"inactivity",
- integer_to_list(
- trunc(MaxInactivity/1000))},
- {"maxpause",
- integer_to_list(MaxPause)},
- {"polling",
- integer_to_list(
- trunc(?MIN_POLLING/1000000))},
- {"ver", ?BOSH_VERSION},
- {"from", From},
- {"secure", "true"} %% we're always being secure
- ] ++ BOSH_attribs,OutEls})};
- {error, _} ->
- {200, ?HEADER, "<body type='terminate' "
- "condition='host-unknown' "
- "xmlns='"++?NS_HTTP_BIND++"'/>"}
- end
- end;
+ ?DEBUG("OutPacket: ~p", [OutputEls++OutPacket]),
+ prepare_outpacket_response(Sess, Rid, OutputEls++OutPacket, StreamStart);
{'EXIT', {shutdown, _}} ->
{200, ?HEADER, "<body type='terminate' condition='system-shutdown' xmlns='"++?NS_HTTP_BIND++"'/>"};
{'EXIT', _Reason} ->
{200, ?HEADER, "<body type='terminate' xmlns='"++?NS_HTTP_BIND++"'/>"}
end.
+%% Send output payloads on establised sessions
+prepare_outpacket_response(Sess, _Rid, OutPacket, false) ->
+ case catch send_outpacket(Sess, OutPacket) of
+ {'EXIT', _Reason} ->
+ {200, ?HEADER,
+ "<body type='terminate' xmlns='"++
+ ?NS_HTTP_BIND++"'/>"};
+ SendRes ->
+ SendRes
+ end;
+%% Handle a new session along with its output payload
+prepare_outpacket_response(#http_bind{id=Sid, wait=Wait,
+ hold=Hold, to=To}=Sess,
+ Rid, OutPacket, true) ->
+ case OutPacket of
+ [{xmlstreamstart, _, OutAttrs} | Els] ->
+ AuthID = xml:get_attr_s("id", OutAttrs),
+ From = xml:get_attr_s("from", OutAttrs),
+ Version = xml:get_attr_s("version", OutAttrs),
+ OutEls =
+ case Els of
+ [] ->
+ [];
+ [{xmlstreamelement,
+ {xmlelement, "stream:features",
+ StreamAttribs, StreamEls}}
+ | StreamTail] ->
+ TypedTail =
+ [check_default_xmlns(OEl) ||
+ {xmlstreamelement, OEl} <-
+ StreamTail],
+ [{xmlelement, "stream:features",
+ [{"xmlns:stream",
+ ?NS_STREAM}] ++
+ StreamAttribs, StreamEls}] ++
+ TypedTail;
+ StreamTail ->
+ [check_default_xmlns(OEl) ||
+ {xmlstreamelement, OEl} <-
+ StreamTail]
+ end,
+ case OutEls of
+ [] ->
+ prepare_response(Sess, Rid, OutPacket, true);
+ [{xmlelement,
+ "stream:error",_,_}] ->
+ {200, ?HEADER, "<body type='terminate' "
+ "condition='host-unknown' "
+ "xmlns='"++?NS_HTTP_BIND++"'/>"};
+ _ ->
+ BOSH_attribs =
+ [{"authid", AuthID},
+ {"xmlns:xmpp", ?NS_BOSH},
+ {"xmlns:stream", ?NS_STREAM}] ++
+ case OutEls of
+ [] ->
+ [];
+ _ ->
+ [{"xmpp:version", Version}]
+ end,
+ MaxInactivity = get_max_inactivity(To, ?MAX_INACTIVITY),
+ MaxPause = get_max_pause(To),
+ {200, ?HEADER,
+ xml:element_to_string(
+ {xmlelement,"body",
+ [{"xmlns",
+ ?NS_HTTP_BIND},
+ {"sid", Sid},
+ {"wait", integer_to_list(Wait)},
+ {"requests", integer_to_list(Hold+1)},
+ {"inactivity",
+ integer_to_list(
+ trunc(MaxInactivity/1000))},
+ {"maxpause",
+ integer_to_list(MaxPause)},
+ {"polling",
+ integer_to_list(
+ trunc(?MIN_POLLING/1000000))},
+ {"ver", ?BOSH_VERSION},
+ {"from", From},
+ {"secure", "true"} %% we're always being secure
+ ] ++ BOSH_attribs,OutEls})}
+ end;
+ _ ->
+ {200, ?HEADER, "<body type='terminate' "
+ "condition='internal-server-error' "
+ "xmlns='"++?NS_HTTP_BIND++"'/>"}
+ end.
+
+
http_get(#http_bind{pid = FsmRef, wait = Wait, hold = Hold}, Rid) ->
gen_fsm:sync_send_all_state_event(
FsmRef, {http_get, Rid, Wait, Hold}, 2 * ?MAX_WAIT * 1000).