mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-24 16:23:40 +01:00
exmpp fixes in http_bind (thanks to Karim Gemayel)
SVN Revision: 2929
This commit is contained in:
parent
f20d2bb2ff
commit
e98df7acb1
@ -37,9 +37,7 @@
|
|||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
-include("ejabberd_http.hrl").
|
-include("ejabberd_http.hrl").
|
||||||
|
-include_lib("exmpp/include/exmpp.hrl").
|
||||||
%% TODO: Use exmpp library instead of including this
|
|
||||||
-define(NS_STREAM, "http://etherx.jabber.org/streams").
|
|
||||||
|
|
||||||
-record(http_bind, {id, pid, to, hold, wait, version}).
|
-record(http_bind, {id, pid, to, hold, wait, version}).
|
||||||
|
|
||||||
@ -90,9 +88,6 @@
|
|||||||
-endif.
|
-endif.
|
||||||
|
|
||||||
-define(BOSH_VERSION, "1.8").
|
-define(BOSH_VERSION, "1.8").
|
||||||
-define(NS_CLIENT, "jabber:client").
|
|
||||||
-define(NS_BOSH, "urn:xmpp:xbosh").
|
|
||||||
-define(NS_HTTP_BIND, "http://jabber.org/protocol/httpbind").
|
|
||||||
|
|
||||||
-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
|
||||||
@ -183,7 +178,7 @@ process_request(Data, IP) ->
|
|||||||
?ERROR_MSG("Session not created (Improper addressing)", []),
|
?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_s ++ "'/>"};
|
||||||
XmppDomain ->
|
XmppDomain ->
|
||||||
%% create new session
|
%% create new session
|
||||||
Sid = sha:sha(term_to_binary({now(), make_ref()})),
|
Sid = sha:sha(term_to_binary({now(), make_ref()})),
|
||||||
@ -191,7 +186,7 @@ process_request(Data, IP) ->
|
|||||||
{error, _} ->
|
{error, _} ->
|
||||||
{200, ?HEADER, "<body type='terminate' "
|
{200, ?HEADER, "<body type='terminate' "
|
||||||
"condition='internal-server-error' "
|
"condition='internal-server-error' "
|
||||||
"xmlns='" ++ ?NS_HTTP_BIND ++ "'>BOSH module not started</body>"};
|
"xmlns='" ++ ?NS_HTTP_BIND_s ++ "'>BOSH module not started</body>"};
|
||||||
{ok, Pid} ->
|
{ok, Pid} ->
|
||||||
handle_session_start(
|
handle_session_start(
|
||||||
Pid, XmppDomain, Sid, Rid, Attrs,
|
Pid, XmppDomain, Sid, Rid, Attrs,
|
||||||
@ -224,7 +219,7 @@ process_request(Data, IP) ->
|
|||||||
gen_fsm:sync_send_all_state_event(FsmRef, {stop, close}),
|
gen_fsm:sync_send_all_state_event(FsmRef, {stop, close}),
|
||||||
{200, ?HEADER, "<body type='terminate' "
|
{200, ?HEADER, "<body type='terminate' "
|
||||||
"condition='undefined-condition' "
|
"condition='undefined-condition' "
|
||||||
"xmlns='" ++ ?NS_HTTP_BIND ++ "'>Request Too Large</body>"}
|
"xmlns='" ++ ?NS_HTTP_BIND_s ++ "'>Request Too Large</body>"}
|
||||||
end;
|
end;
|
||||||
_ ->
|
_ ->
|
||||||
?DEBUG("Received bad request: ~p", [Data]),
|
?DEBUG("Received bad request: ~p", [Data]),
|
||||||
@ -698,16 +693,16 @@ process_http_put(#http_put{rid = Rid, attrs = Attrs, payload = Payload,
|
|||||||
C2SPid,
|
C2SPid,
|
||||||
{xmlstreamstart, "stream:stream",
|
{xmlstreamstart, "stream:stream",
|
||||||
[{"to", To},
|
[{"to", To},
|
||||||
{"xmlns", ?NS_CLIENT},
|
{"xmlns", ?NS_JABBER_CLIENT_s},
|
||||||
{"xmlns:stream", ?NS_STREAM}]});
|
{"xmlns:stream", ?NS_XMPP_s}]});
|
||||||
{To, Version} ->
|
{To, Version} ->
|
||||||
gen_fsm:send_event(
|
gen_fsm:send_event(
|
||||||
C2SPid,
|
C2SPid,
|
||||||
{xmlstreamstart, "stream:stream",
|
{xmlstreamstart, "stream:stream",
|
||||||
[{"to", To},
|
[{"to", To},
|
||||||
{"xmlns", ?NS_CLIENT},
|
{"xmlns", ?NS_JABBER_CLIENT_s},
|
||||||
{"version", Version},
|
{"version", Version},
|
||||||
{"xmlns:stream", ?NS_STREAM}]});
|
{"xmlns:stream", ?NS_XMPP_s}]});
|
||||||
_ ->
|
_ ->
|
||||||
ok
|
ok
|
||||||
end,
|
end,
|
||||||
@ -776,12 +771,12 @@ handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize, StreamStart, IP) ->
|
|||||||
%{200, ?HEADER,
|
%{200, ?HEADER,
|
||||||
% xml:element_to_string(
|
% xml:element_to_string(
|
||||||
% {xmlelement, "body",
|
% {xmlelement, "body",
|
||||||
% [{"xmlns", ?NS_HTTP_BIND},
|
% [{"xmlns", ?NS_HTTP_BIND_s},
|
||||||
% {"type", "error"}], []})};
|
% {"type", "error"}], []})};
|
||||||
handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize,
|
handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize,
|
||||||
StreamStart, IP);
|
StreamStart, IP);
|
||||||
{buffered, _Sess} ->
|
{buffered, _Sess} ->
|
||||||
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND++"'/>"};
|
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
{ok, Sess} ->
|
{ok, Sess} ->
|
||||||
prepare_response(Sess, Rid, Attrs, StreamStart)
|
prepare_response(Sess, Rid, Attrs, StreamStart)
|
||||||
end.
|
end.
|
||||||
@ -812,24 +807,51 @@ handle_http_put_error(Reason, #http_bind{pid=FsmRef, version=Version})
|
|||||||
not_exists ->
|
not_exists ->
|
||||||
{200, ?HEADER,
|
{200, ?HEADER,
|
||||||
xml:element_to_string(
|
xml:element_to_string(
|
||||||
{xmlelement, "body",
|
#xmlel{name = 'body',
|
||||||
[{"xmlns", ?NS_HTTP_BIND},
|
ns = ?NS_HTTP_BIND_s,
|
||||||
{"type", "terminate"},
|
attrs = [
|
||||||
{"condition", "item-not-found"}], []})};
|
#xmlattr{name = 'type',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = 'terminate'
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'type',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = 'item-not-found'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})};
|
||||||
bad_key ->
|
bad_key ->
|
||||||
{200, ?HEADER,
|
{200, ?HEADER,
|
||||||
xml:element_to_string(
|
xml:element_to_string(
|
||||||
{xmlelement, "body",
|
#xmlel{name = 'body',
|
||||||
[{"xmlns", ?NS_HTTP_BIND},
|
ns = ?NS_HTTP_BIND_s,
|
||||||
{"type", "terminate"},
|
attrs = [
|
||||||
{"condition", "item-not-found"}], []})};
|
#xmlattr{name = 'type',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = 'terminate'
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'type',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = 'item-not-found'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})};
|
||||||
polling_too_frequently ->
|
polling_too_frequently ->
|
||||||
{200, ?HEADER,
|
{200, ?HEADER,
|
||||||
xml:element_to_string(
|
xml:element_to_string(
|
||||||
{xmlelement, "body",
|
#xmlel{name = 'body',
|
||||||
[{"xmlns", ?NS_HTTP_BIND},
|
ns = ?NS_HTTP_BIND_s,
|
||||||
{"type", "terminate"},
|
attrs = [
|
||||||
{"condition", "policy-violation"}], []})}
|
#xmlattr{name = 'type',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = 'terminate'
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'type',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = 'policy-violation'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})}
|
||||||
end;
|
end;
|
||||||
handle_http_put_error(Reason, #http_bind{pid=FsmRef}) ->
|
handle_http_put_error(Reason, #http_bind{pid=FsmRef}) ->
|
||||||
gen_fsm:sync_send_all_state_event(FsmRef,{stop, {put_error_no_version, Reason}}),
|
gen_fsm:sync_send_all_state_event(FsmRef,{stop, {put_error_no_version, Reason}}),
|
||||||
@ -893,11 +915,11 @@ prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess,
|
|||||||
%% actually it would be better if we could completely
|
%% actually it would be better if we could completely
|
||||||
%% cancel this request, but then we would have to hack
|
%% cancel this request, but then we would have to hack
|
||||||
%% ejabberd_http and I'm too lazy now
|
%% ejabberd_http and I'm too lazy now
|
||||||
{200, ?HEADER, "<body type='error' xmlns='"++?NS_HTTP_BIND++"'/>"};
|
{200, ?HEADER, "<body type='error' xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
{ok, empty} ->
|
{ok, empty} ->
|
||||||
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND++"'/>"};
|
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
{ok, terminate} ->
|
{ok, terminate} ->
|
||||||
{200, ?HEADER, "<body type='terminate' xmlns='"++?NS_HTTP_BIND++"'/>"};
|
{200, ?HEADER, "<body type='terminate' xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
{ok, ROutPacket} ->
|
{ok, ROutPacket} ->
|
||||||
OutPacket = lists:reverse(ROutPacket),
|
OutPacket = lists:reverse(ROutPacket),
|
||||||
?DEBUG("OutPacket: ~p", [OutPacket]),
|
?DEBUG("OutPacket: ~p", [OutPacket]),
|
||||||
@ -915,17 +937,26 @@ prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess,
|
|||||||
[] ->
|
[] ->
|
||||||
[];
|
[];
|
||||||
[{xmlstreamelement,
|
[{xmlstreamelement,
|
||||||
{xmlelement, "stream:features",
|
#xmlel{name = 'features',
|
||||||
StreamAttribs, StreamEls}}
|
declared_ns = [{undefined, ?NS_XMPP_pfx}],
|
||||||
|
attrs = StreamAttribs,
|
||||||
|
children = StreamEls}}
|
||||||
| StreamTail] ->
|
| StreamTail] ->
|
||||||
|
% {xmlelement, "stream:features",
|
||||||
|
% StreamAttribs, StreamEls}}
|
||||||
|
% | StreamTail] ->
|
||||||
TypedTail =
|
TypedTail =
|
||||||
[check_default_xmlns(OEl) ||
|
[check_default_xmlns(OEl) ||
|
||||||
{xmlstreamelement, OEl} <-
|
{xmlstreamelement, OEl} <-
|
||||||
StreamTail],
|
StreamTail],
|
||||||
[{xmlelement, "stream:features",
|
[#xmlel{name = 'features',
|
||||||
[{"xmlns:stream",
|
declared_ns = [{?NS_XMPP_s, ?NS_XMPP_pfx}],
|
||||||
?NS_STREAM}] ++
|
attrs = StreamAttribs,
|
||||||
StreamAttribs, StreamEls}] ++
|
children = StreamEls}] ++
|
||||||
|
% [{xmlelement, "stream:features",
|
||||||
|
% [{"xmlns:stream",
|
||||||
|
% ?NS_XMPP_s}] ++
|
||||||
|
% StreamAttribs, StreamEls}] ++
|
||||||
TypedTail;
|
TypedTail;
|
||||||
StreamTail ->
|
StreamTail ->
|
||||||
[check_default_xmlns(OEl) ||
|
[check_default_xmlns(OEl) ||
|
||||||
@ -934,8 +965,8 @@ prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess,
|
|||||||
end,
|
end,
|
||||||
BOSH_attribs =
|
BOSH_attribs =
|
||||||
[{"authid", AuthID},
|
[{"authid", AuthID},
|
||||||
{"xmlns:xmpp", ?NS_BOSH},
|
{"xmlns:xmpp", ?NS_BOSH_s},
|
||||||
{"xmlns:stream", ?NS_STREAM}] ++
|
{"xmlns:stream", ?NS_XMPP_s}] ++
|
||||||
case OutEls of
|
case OutEls of
|
||||||
[] ->
|
[] ->
|
||||||
[];
|
[];
|
||||||
@ -946,34 +977,76 @@ prepare_response(#http_bind{id=Sid, wait=Wait, hold=Hold, to=To}=Sess,
|
|||||||
MaxPause = get_max_pause(To),
|
MaxPause = get_max_pause(To),
|
||||||
{200, ?HEADER,
|
{200, ?HEADER,
|
||||||
xml:element_to_string(
|
xml:element_to_string(
|
||||||
{xmlelement,"body",
|
#xmlel{name = 'body',
|
||||||
[{"xmlns",
|
ns = ?NS_HTTP_BIND_s,
|
||||||
?NS_HTTP_BIND},
|
attrs = [
|
||||||
{"sid", Sid},
|
#xmlattr{name = 'sid',
|
||||||
{"wait", integer_to_list(Wait)},
|
ns = ?NS_HTTP_BIND_s,
|
||||||
{"requests", integer_to_list(Hold+1)},
|
value = Sid
|
||||||
{"inactivity",
|
},
|
||||||
integer_to_list(
|
#xmlattr{name = 'wait',
|
||||||
trunc(MaxInactivity/1000))},
|
ns = ?NS_HTTP_BIND_s,
|
||||||
{"maxpause",
|
value = integer_to_list(Wait)
|
||||||
integer_to_list(MaxPause)},
|
},
|
||||||
{"polling",
|
#xmlattr{name = 'requests',
|
||||||
integer_to_list(
|
ns = ?NS_HTTP_BIND_s,
|
||||||
trunc(?MIN_POLLING/1000000))},
|
value = integer_to_list(Hold+1)
|
||||||
{"ver", ?BOSH_VERSION},
|
},
|
||||||
{"from", From},
|
#xmlattr{name = 'inactivity',
|
||||||
{"secure", "true"} %% we're always being secure
|
ns = ?NS_HTTP_BIND_s,
|
||||||
] ++ BOSH_attribs,OutEls})};
|
value = integer_to_list(trunc(MaxInactivity/1000))
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'maxpause',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = integer_to_list(MaxPause)
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'polling',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = integer_to_list(trunc(?MIN_POLLING/1000000))
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'ver',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = ?BOSH_VERSION
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'from',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = From
|
||||||
|
},
|
||||||
|
#xmlattr{name = 'secure',
|
||||||
|
ns = ?NS_HTTP_BIND_s,
|
||||||
|
value = "true"
|
||||||
|
},
|
||||||
|
BOSH_attribs
|
||||||
|
],
|
||||||
|
children = OutEls})};
|
||||||
|
% {xmlelement,"body",
|
||||||
|
% [{"xmlns",
|
||||||
|
% ?NS_HTTP_BIND_s},
|
||||||
|
% {"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, _} ->
|
{error, _} ->
|
||||||
{200, ?HEADER, "<body type='terminate' "
|
{200, ?HEADER, "<body type='terminate' "
|
||||||
"condition='host-unknown' "
|
"condition='host-unknown' "
|
||||||
"xmlns='"++?NS_HTTP_BIND++"'/>"}
|
"xmlns='"++?NS_HTTP_BIND_s++"'/>"}
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
{'EXIT', {shutdown, _}} ->
|
{'EXIT', {shutdown, _}} ->
|
||||||
{200, ?HEADER, "<body type='terminate' condition='system-shutdown' xmlns='"++?NS_HTTP_BIND++"'/>"};
|
{200, ?HEADER, "<body type='terminate' condition='system-shutdown' xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
{'EXIT', _Reason} ->
|
{'EXIT', _Reason} ->
|
||||||
{200, ?HEADER, "<body type='terminate' xmlns='"++?NS_HTTP_BIND++"'/>"}
|
{200, ?HEADER, "<body type='terminate' xmlns='"++?NS_HTTP_BIND_s++"'/>"}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
http_get(#http_bind{pid = FsmRef, wait = Wait, hold = Hold}, Rid) ->
|
http_get(#http_bind{pid = FsmRef, wait = Wait, hold = Hold}, Rid) ->
|
||||||
@ -983,10 +1056,10 @@ http_get(#http_bind{pid = FsmRef, wait = Wait, hold = Hold}, Rid) ->
|
|||||||
send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
||||||
case OutPacket of
|
case OutPacket of
|
||||||
[] ->
|
[] ->
|
||||||
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND++"'/>"};
|
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
[{xmlstreamend, _}] ->
|
[{xmlstreamend, _}] ->
|
||||||
gen_fsm:sync_send_all_state_event(FsmRef,{stop,stream_closed}),
|
gen_fsm:sync_send_all_state_event(FsmRef,{stop,stream_closed}),
|
||||||
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND++"'/>"};
|
{200, ?HEADER, "<body xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
_ ->
|
_ ->
|
||||||
%% TODO: We parse to add a default namespace to packet,
|
%% TODO: We parse to add a default namespace to packet,
|
||||||
%% The spec says adding the jabber:client namespace if
|
%% The spec says adding the jabber:client namespace if
|
||||||
@ -996,7 +1069,9 @@ send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
|||||||
%% packet in most case.
|
%% packet in most case.
|
||||||
AllElements =
|
AllElements =
|
||||||
lists:all(fun({xmlstreamelement,
|
lists:all(fun({xmlstreamelement,
|
||||||
{xmlelement, "stream:error", _, _}}) -> false;
|
#xmlel{name = 'error',
|
||||||
|
declared_ns = [{undefined, ?NS_XMPP_pfx}]}}) -> false;
|
||||||
|
% {xmlelement, "stream:error", _, _}}) -> false;
|
||||||
({xmlstreamelement, _}) -> true;
|
({xmlstreamelement, _}) -> true;
|
||||||
(_) -> false
|
(_) -> false
|
||||||
end, OutPacket),
|
end, OutPacket),
|
||||||
@ -1005,10 +1080,13 @@ send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
|||||||
TypedEls = [check_default_xmlns(OEl) ||
|
TypedEls = [check_default_xmlns(OEl) ||
|
||||||
{xmlstreamelement, OEl} <- OutPacket],
|
{xmlstreamelement, OEl} <- OutPacket],
|
||||||
Body = xml:element_to_string(
|
Body = xml:element_to_string(
|
||||||
{xmlelement,"body",
|
#xmlel{name = 'body',
|
||||||
[{"xmlns",
|
ns = ?NS_HTTP_BIND_s,
|
||||||
?NS_HTTP_BIND}],
|
children = TypedEls}),
|
||||||
TypedEls}),
|
% {xmlelement,"body",
|
||||||
|
% [{"xmlns",
|
||||||
|
% ?NS_HTTP_BIND_s}],
|
||||||
|
% TypedEls}),
|
||||||
?DEBUG(" --- outgoing data --- ~n~s~n --- END --- ~n",
|
?DEBUG(" --- outgoing data --- ~n~s~n --- END --- ~n",
|
||||||
[Body]),
|
[Body]),
|
||||||
{200, ?HEADER, Body};
|
{200, ?HEADER, Body};
|
||||||
@ -1018,19 +1096,27 @@ send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
|||||||
OutEls =
|
OutEls =
|
||||||
case SEls of
|
case SEls of
|
||||||
[{xmlstreamelement,
|
[{xmlstreamelement,
|
||||||
{xmlelement,
|
#xmlel{name = 'features',
|
||||||
"stream:features",
|
declared_ns = [{undefined, 'stream'}],
|
||||||
StreamAttribs, StreamEls}} |
|
attrs = StreamAttribs,
|
||||||
|
children = StreamEls}} |
|
||||||
|
% {xmlelement,
|
||||||
|
% "stream:features",
|
||||||
|
% StreamAttribs, StreamEls}} |
|
||||||
StreamTail] ->
|
StreamTail] ->
|
||||||
TypedTail =
|
TypedTail =
|
||||||
[check_default_xmlns(OEl) ||
|
[check_default_xmlns(OEl) ||
|
||||||
{xmlstreamelement, OEl} <-
|
{xmlstreamelement, OEl} <-
|
||||||
StreamTail],
|
StreamTail],
|
||||||
[{xmlelement,
|
[#xmlel{name = 'features',
|
||||||
"stream:features",
|
declared_ns = [{?NS_XMPP_s, ?NS_XMPP_pfx}],
|
||||||
[{"xmlns:stream",
|
attrs = StreamAttribs,
|
||||||
?NS_STREAM}] ++
|
children = StreamEls}] ++
|
||||||
StreamAttribs, StreamEls}] ++
|
% [{xmlelement,
|
||||||
|
% "stream:features",
|
||||||
|
% [{"xmlns:stream",
|
||||||
|
% ?NS_XMPP_s}] ++
|
||||||
|
% StreamAttribs, StreamEls}] ++
|
||||||
TypedTail;
|
TypedTail;
|
||||||
StreamTail ->
|
StreamTail ->
|
||||||
[check_default_xmlns(OEl) ||
|
[check_default_xmlns(OEl) ||
|
||||||
@ -1039,16 +1125,21 @@ send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
|||||||
end,
|
end,
|
||||||
{200, ?HEADER,
|
{200, ?HEADER,
|
||||||
xml:element_to_string(
|
xml:element_to_string(
|
||||||
{xmlelement,"body",
|
#xmlel{name = 'body',
|
||||||
[{"xmlns",
|
ns = ?NS_HTTP_BIND_s,
|
||||||
?NS_HTTP_BIND}],
|
children = OutEls})};
|
||||||
OutEls})};
|
% {xmlelement,"body",
|
||||||
|
% [{"xmlns",
|
||||||
|
% ?NS_HTTP_BIND_s}],
|
||||||
|
% OutEls})};
|
||||||
_ ->
|
_ ->
|
||||||
SErrCond =
|
SErrCond =
|
||||||
lists:filter(
|
lists:filter(
|
||||||
fun({xmlstreamelement,
|
fun({xmlstreamelement,
|
||||||
{xmlelement, "stream:error",
|
#xmlel{name = 'error',
|
||||||
_, _}}) ->
|
declared_ns = [{undefined, ?NS_XMPP_pfx}]}}) ->
|
||||||
|
% {xmlelement, "stream:error",
|
||||||
|
% _, _}}) ->
|
||||||
true;
|
true;
|
||||||
(_) -> false
|
(_) -> false
|
||||||
end, OutPacket),
|
end, OutPacket),
|
||||||
@ -1057,7 +1148,8 @@ send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
|||||||
[] ->
|
[] ->
|
||||||
null;
|
null;
|
||||||
[{xmlstreamelement,
|
[{xmlstreamelement,
|
||||||
{xmlelement, _, _, _Cond} =
|
#xmlel{children = _Cond} =
|
||||||
|
% {xmlelement, _, _, _Cond} =
|
||||||
StreamErrorTag} | _] ->
|
StreamErrorTag} | _] ->
|
||||||
[StreamErrorTag]
|
[StreamErrorTag]
|
||||||
end,
|
end,
|
||||||
@ -1068,13 +1160,13 @@ send_outpacket(#http_bind{pid = FsmRef}, OutPacket) ->
|
|||||||
{200, ?HEADER,
|
{200, ?HEADER,
|
||||||
"<body type='terminate' "
|
"<body type='terminate' "
|
||||||
"condition='internal-server-error' "
|
"condition='internal-server-error' "
|
||||||
"xmlns='"++?NS_HTTP_BIND++"'/>"};
|
"xmlns='"++?NS_HTTP_BIND_s++"'/>"};
|
||||||
_ ->
|
_ ->
|
||||||
{200, ?HEADER,
|
{200, ?HEADER,
|
||||||
"<body type='terminate' "
|
"<body type='terminate' "
|
||||||
"condition='remote-stream-error' "
|
"condition='remote-stream-error' "
|
||||||
"xmlns='"++?NS_HTTP_BIND++"' " ++
|
"xmlns='"++?NS_HTTP_BIND_s++"' " ++
|
||||||
"xmlns:stream='"++?NS_STREAM++"'>" ++
|
"xmlns:stream='"++?NS_XMPP_s++"'>" ++
|
||||||
elements_to_string(StreamErrCond) ++
|
elements_to_string(StreamErrCond) ++
|
||||||
"</body>"}
|
"</body>"}
|
||||||
end
|
end
|
||||||
@ -1087,13 +1179,19 @@ parse_request(Data, PayloadSize, MaxStanzaSize) ->
|
|||||||
%% MR: I do not think it works if put put several elements in the
|
%% MR: I do not think it works if put put several elements in the
|
||||||
%% same body:
|
%% same body:
|
||||||
case xml_stream:parse_element(Data) of
|
case xml_stream:parse_element(Data) of
|
||||||
{xmlelement, "body", Attrs, Els} ->
|
#xmlel{name = 'body',
|
||||||
Xmlns = xml:get_attr_s("xmlns",Attrs),
|
ns = Xmlns,
|
||||||
|
attrs = Attrs,
|
||||||
|
children = Els} = Xml->
|
||||||
|
% {xmlelement, "body", Attrs, Els} ->
|
||||||
|
% Xmlns = xml:get_attr_s("xmlns",Attrs),
|
||||||
if
|
if
|
||||||
Xmlns /= ?NS_HTTP_BIND ->
|
Xmlns /= ?NS_HTTP_BIND_s ->
|
||||||
{error, bad_request};
|
{error, bad_request};
|
||||||
true ->
|
true ->
|
||||||
case catch list_to_integer(xml:get_attr_s("rid", Attrs)) of
|
%case catch list_to_integer(xml:get_attr_s("rid", Attrs)) of
|
||||||
|
case catch list_to_integer(exmpp_xml:get_attribute_as_list(Xml, "rid", "")) of
|
||||||
|
|
||||||
{'EXIT', _} ->
|
{'EXIT', _} ->
|
||||||
{error, bad_request};
|
{error, bad_request};
|
||||||
Rid ->
|
Rid ->
|
||||||
@ -1102,12 +1200,14 @@ parse_request(Data, PayloadSize, MaxStanzaSize) ->
|
|||||||
lists:filter(
|
lists:filter(
|
||||||
fun(I) ->
|
fun(I) ->
|
||||||
case I of
|
case I of
|
||||||
{xmlelement, _, _, _} ->
|
#xmlel{} ->
|
||||||
|
%{xmlelement, _, _, _} ->
|
||||||
true;
|
true;
|
||||||
_ ->
|
_ ->
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end, Els),
|
end, Els),
|
||||||
|
% Suggestion : Sid = exmpp_xml:get_attribute_as_list(Xml, "sid", ""),
|
||||||
Sid = xml:get_attr_s("sid",Attrs),
|
Sid = xml:get_attr_s("sid",Attrs),
|
||||||
if
|
if
|
||||||
PayloadSize =< MaxStanzaSize ->
|
PayloadSize =< MaxStanzaSize ->
|
||||||
@ -1117,7 +1217,8 @@ parse_request(Data, PayloadSize, MaxStanzaSize) ->
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
{xmlelement, _Name, _Attrs, _Els} ->
|
#xmlel{} ->
|
||||||
|
% {xmlelement, _Name, _Attrs, _Els} ->
|
||||||
{error, bad_request};
|
{error, bad_request};
|
||||||
{error, _Reason} ->
|
{error, _Reason} ->
|
||||||
{error, bad_request}
|
{error, bad_request}
|
||||||
@ -1178,9 +1279,12 @@ tnow() ->
|
|||||||
{TMegSec, TSec, TMSec} = now(),
|
{TMegSec, TSec, TMSec} = now(),
|
||||||
(TMegSec * 1000000 + TSec) * 1000000 + TMSec.
|
(TMegSec * 1000000 + TSec) * 1000000 + TMSec.
|
||||||
|
|
||||||
check_default_xmlns({xmlelement, Name, Attrs, Els} = El) ->
|
check_default_xmlns(#xmlel{name = Name, ns = Xmlns, attrs = Attrs, children = Els} = El) ->
|
||||||
case xml:get_tag_attr_s("xmlns", El) of
|
%check_default_xmlns({xmlelement, Name, Attrs, Els} = El) ->
|
||||||
"" -> {xmlelement, Name, [{"xmlns", ?NS_CLIENT} | Attrs], Els};
|
case Xmlns of
|
||||||
|
% case xml:get_tag_attr_s("xmlns", El) of
|
||||||
|
"" -> #xmlel{name = Name, ns = ?NS_JABBER_CLIENT_s, attrs = Attrs, children = Els};
|
||||||
|
% "" -> {xmlelement, Name, [{"xmlns", ?NS_JABBER_CLIENT_s} | Attrs], Els};
|
||||||
_ -> El
|
_ -> El
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user