Mercurial > 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 |
| parents | 04662cc35280 |
| children | 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 |
