Mercurial > prosody-hg
comparison plugins/mod_c2s.lua @ 4964:c9b8ec3eb1e9
mod_c2s: Don't call ondisconnect manually on close, it is now called by net.server. Replace with inline code for destroying the session, and also waiting for a reply </stream:stream> if there is a chance of further data sent by the client. session.send() on a half-closed stream returns false (and does not deliver the data).
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 22 Jul 2012 16:59:12 +0100 |
| parents | 9cc934f49df0 |
| children | 9da430b69f13 |
comparison
equal
deleted
inserted
replaced
| 4963:54e2c83af127 | 4964:c9b8ec3eb1e9 |
|---|---|
| 22 local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; | 22 local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; |
| 23 | 23 |
| 24 local log = module._log; | 24 local log = module._log; |
| 25 | 25 |
| 26 local c2s_timeout = module:get_option_number("c2s_timeout"); | 26 local c2s_timeout = module:get_option_number("c2s_timeout"); |
| 27 local stream_close_timeout = module:get_option_number("c2s_close_timeout", 5); | |
| 27 local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); | 28 local opt_keepalives = module:get_option_boolean("tcp_keepalives", false); |
| 28 | 29 |
| 29 local sessions = module:shared("sessions"); | 30 local sessions = module:shared("sessions"); |
| 30 | 31 |
| 31 local stream_callbacks = { default_ns = "jabber:client", handlestanza = core_process_stanza }; | 32 local stream_callbacks = { default_ns = "jabber:client", handlestanza = core_process_stanza }; |
| 141 session.send(reason); | 142 session.send(reason); |
| 142 end | 143 end |
| 143 end | 144 end |
| 144 end | 145 end |
| 145 session.send("</stream:stream>"); | 146 session.send("</stream:stream>"); |
| 146 session.conn:close(); | 147 |
| 147 listener.ondisconnect(session.conn, (reason and (reason.text or reason.condition)) or reason or "session closed"); | 148 function session.send() return false; end |
| 149 | |
| 150 local reason = (reason and (reason.text or reason.condition)) or reason or "session closed"; | |
| 151 session.log("info", "c2s stream for %s closed: %s", session.full_jid or ("<"..session.ip..">"), reason); | |
| 152 | |
| 153 -- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote | |
| 154 local conn = session.conn; | |
| 155 if reason == "session closed" and not session.notopen and session.type == "c2s" then | |
| 156 -- Grace time to process data from authenticated cleanly-closed stream | |
| 157 add_task(stream_close_timeout, function () | |
| 158 if not session.destroyed then | |
| 159 session.log("warn", "Failed to receive a stream close response, closing connection anyway..."); | |
| 160 sm_destroy_session(session, reason); | |
| 161 conn:close(); | |
| 162 end | |
| 163 end); | |
| 164 else | |
| 165 sm_destroy_session(session, reason); | |
| 166 conn:close(); | |
| 167 end | |
| 148 end | 168 end |
| 149 end | 169 end |
| 150 | 170 |
| 151 --- Port listener | 171 --- Port listener |
| 152 function listener.onconnect(conn) | 172 function listener.onconnect(conn) |
| 206 end | 226 end |
| 207 | 227 |
| 208 function listener.ondisconnect(conn, err) | 228 function listener.ondisconnect(conn, err) |
| 209 local session = sessions[conn]; | 229 local session = sessions[conn]; |
| 210 if session then | 230 if session then |
| 211 (session.log or log)("info", "Client disconnected: %s", err); | 231 (session.log or log)("info", "Client disconnected: %s", err or "connection closed"); |
| 212 sm_destroy_session(session, err); | 232 sm_destroy_session(session, err); |
| 213 sessions[conn] = nil; | 233 sessions[conn] = nil; |
| 214 session = nil; | |
| 215 end | 234 end |
| 216 end | 235 end |
| 217 | 236 |
| 218 function listener.associate_session(conn, session) | 237 function listener.associate_session(conn, session) |
| 219 sessions[conn] = session; | 238 sessions[conn] = session; |
