Software /
code /
prosody-modules
Comparison
mod_websocket/mod_websocket.lua @ 692:2de21fa40382
mod_websocket: Make sending a self-closing <stream:stream> tag configurable
Due to limitations in browser's XML parsers most (all?) existing client
implementations require the <stream:stream/> tag to be self-closing.
This commit makes this behaviour configurable, to enable "proper" implementations.
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Mon, 28 May 2012 00:52:47 +0200 |
parent | 691:04662cc35280 |
child | 693:7d165cd6168c |
comparison
equal
deleted
inserted
replaced
691:04662cc35280 | 692:2de21fa40382 |
---|---|
29 | 29 |
30 local log = module._log; | 30 local log = module._log; |
31 | 31 |
32 local c2s_timeout = module:get_option_number("c2s_timeout"); | 32 local c2s_timeout = module:get_option_number("c2s_timeout"); |
33 local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); | 33 local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); |
34 local self_closing_stream = module:get_option_boolean("websocket_self_closing_stream", true); | |
34 | 35 |
35 local sessions = module:shared("sessions"); | 36 local sessions = module:shared("sessions"); |
36 | 37 |
37 local stream_callbacks = { default_ns = "jabber:client", handlestanza = core_process_stanza }; | 38 local stream_callbacks = { default_ns = "jabber:client", handlestanza = core_process_stanza }; |
38 local listener = {}; | 39 local listener = {}; |
132 session:close{ condition = "host-unknown", text = "This server does not serve "..tostring(session.host)}; | 133 session:close{ condition = "host-unknown", text = "This server does not serve "..tostring(session.host)}; |
133 return; | 134 return; |
134 end | 135 end |
135 | 136 |
136 -- COMPAT: Current client implementations need this to be self-closing | 137 -- COMPAT: Current client implementations need this to be self-closing |
137 send("<?xml version='1.0'?>"..(tostring(st.stanza("stream:stream", { | 138 if self_closing_stream then |
138 xmlns = 'jabber:client', ["xmlns:stream"] = 'http://etherx.jabber.org/streams'; | 139 send("<?xml version='1.0'?>"..tostring(st.stanza("stream:stream", { |
139 id = session.streamid, from = session.host, version = '1.0', ["xml:lang"] = 'en' }):top_tag()):gsub(">", "/>"))); | 140 xmlns = 'jabber:client', ["xmlns:stream"] = 'http://etherx.jabber.org/streams'; |
141 id = session.streamid, from = session.host, version = '1.0', ["xml:lang"] = 'en' }))); | |
142 else | |
143 send("<?xml version='1.0'?>"..st.stanza("stream:stream", { | |
144 xmlns = 'jabber:client', ["xmlns:stream"] = 'http://etherx.jabber.org/streams'; | |
145 id = session.streamid, from = session.host, version = '1.0', ["xml:lang"] = 'en' }):top_tag()); | |
146 end | |
140 | 147 |
141 (session.log or log)("debug", "Sent reply <stream:stream> to client"); | 148 (session.log or log)("debug", "Sent reply <stream:stream> to client"); |
142 session.notopen = nil; | 149 session.notopen = nil; |
143 | 150 |
144 -- If session.secure is *false* (not nil) then it means we /were/ encrypting | 151 -- If session.secure is *false* (not nil) then it means we /were/ encrypting |
197 --- Session methods | 204 --- Session methods |
198 local function session_close(session, reason) | 205 local function session_close(session, reason) |
199 local log = session.log or log; | 206 local log = session.log or log; |
200 if session.conn then | 207 if session.conn then |
201 if session.notopen then | 208 if session.notopen then |
202 session.send("<?xml version='1.0'?>"); | 209 -- COMPAT: Current client implementations need this to be self-closing |
203 session.send(st.stanza("stream:stream", default_stream_attr):top_tag()); | 210 if self_closing_stream then |
211 session.send("<?xml version='1.0'?>"..tostring(st.stanza("stream:stream", default_stream_attr))); | |
212 else | |
213 session.send("<?xml version='1.0'?>"..st.stanza("stream:stream", default_stream_attr):top_tag()); | |
214 end | |
204 end | 215 end |
205 if reason then | 216 if reason then |
206 if type(reason) == "string" then -- assume stream error | 217 if type(reason) == "string" then -- assume stream error |
207 log("info", "Disconnecting client, <stream:error> is: %s", reason); | 218 log("info", "Disconnecting client, <stream:error> is: %s", reason); |
208 session.send(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' })); | 219 session.send(st.stanza("stream:error"):tag(reason, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' })); |
276 if frame.FIN then | 287 if frame.FIN then |
277 data = buffer; | 288 data = buffer; |
278 buffer = ""; | 289 buffer = ""; |
279 | 290 |
280 -- COMPAT: Current client implementations send a self-closing <stream:stream> | 291 -- COMPAT: Current client implementations send a self-closing <stream:stream> |
281 data = data:gsub("/>$", ">"); | 292 if self_closing_stream then |
293 data = data:gsub("/>$", ">"); | |
294 end | |
282 | 295 |
283 data = filter("bytes/in", data); | 296 data = filter("bytes/in", data); |
284 if data then | 297 if data then |
285 local ok, err = stream:feed(data); | 298 local ok, err = stream:feed(data); |
286 if ok then return; end | 299 if ok then return; end |