Software / code / prosody
Comparison
plugins/mod_compression.lua @ 2286:e0b2d934f316
mod_compression: Enabeling compression for outgoing s2s streams.
| author | Tobias Markmann <tm@ayena.de> |
|---|---|
| date | Mon, 30 Nov 2009 23:23:42 +0100 |
| parent | 2285:3dd7fdee9035 |
| child | 2288:3c17fc919f7b |
comparison
equal
deleted
inserted
replaced
| 2285:3dd7fdee9035 | 2286:e0b2d934f316 |
|---|---|
| 36 | 36 |
| 37 module:hook("s2s-stream-features", | 37 module:hook("s2s-stream-features", |
| 38 function (data) | 38 function (data) |
| 39 local session, features = data.session, data.features; | 39 local session, features = data.session, data.features; |
| 40 -- FIXME only advertise compression support when TLS layer has no compression enabled | 40 -- FIXME only advertise compression support when TLS layer has no compression enabled |
| 41 features:add_child(compression_stream_feature); | 41 if not session.compressed then |
| 42 module:log("debug", "s2s-stream-features YAY YAHOO") | |
| 43 features:add_child(compression_stream_feature); | |
| 44 end | |
| 42 end | 45 end |
| 43 ); | 46 ); |
| 44 | 47 |
| 45 -- S2Sout handling aka the client perspective in the S2S connection | 48 -- S2Sout handling aka the client perspective in the S2S connection |
| 46 module:hook_stanza(xmlns_stream, "features", | 49 module:hook_stanza(xmlns_stream, "features", |
| 95 -- setup compression for a stream | 98 -- setup compression for a stream |
| 96 local function setup_compression(session, deflate_stream) | 99 local function setup_compression(session, deflate_stream) |
| 97 local old_send = (session.sends2s or session.send); | 100 local old_send = (session.sends2s or session.send); |
| 98 | 101 |
| 99 local new_send = function(t) | 102 local new_send = function(t) |
| 103 --TODO: Better code injection in the sending process | |
| 104 session.log(t) | |
| 100 local status, compressed, eof = pcall(deflate_stream, tostring(t), 'sync'); | 105 local status, compressed, eof = pcall(deflate_stream, tostring(t), 'sync'); |
| 101 if status == false then | 106 if status == false then |
| 102 session:close({ | 107 session:close({ |
| 103 condition = "undefined-condition"; | 108 condition = "undefined-condition"; |
| 104 text = compressed; | 109 text = compressed; |
| 105 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed"); | 110 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed"); |
| 106 }); | 111 }); |
| 107 module:log("warn", compressed); | 112 module:log("warn", compressed); |
| 108 return; | 113 return; |
| 109 end | 114 end |
| 110 old_send(compressed); | 115 session.conn:write(compressed); |
| 111 end; | 116 end; |
| 112 | 117 |
| 113 if session.sends2s then session.sends2s = new_send | 118 if session.sends2s then session.sends2s = new_send |
| 114 elseif session.send then session.send = new_send end | 119 elseif session.send then session.send = new_send end |
| 115 end | 120 end |
| 134 | 139 |
| 135 -- TODO Support compression on S2S level too. | 140 -- TODO Support compression on S2S level too. |
| 136 module:add_handler({"s2sout_unauthed", "s2sout"}, "compressed", xmlns_compression_protocol, | 141 module:add_handler({"s2sout_unauthed", "s2sout"}, "compressed", xmlns_compression_protocol, |
| 137 function(session ,stanza) | 142 function(session ,stanza) |
| 138 session.log("debug", "Activating compression...") | 143 session.log("debug", "Activating compression...") |
| 144 -- create deflate and inflate streams | |
| 145 deflate_stream = get_deflate_stream(session); | |
| 146 if not deflate_stream then return end | |
| 147 | |
| 148 inflate_stream = get_inflate_stream(session); | |
| 149 if not inflate_stream then return end | |
| 150 | |
| 151 -- setup compression for session.w | |
| 152 setup_compression(session, deflate_stream); | |
| 153 | |
| 154 -- setup decompression for session.data | |
| 155 setup_decompression(session, inflate_stream); | |
| 156 local session_reset_stream = session.reset_stream; | |
| 157 session.reset_stream = function(session) | |
| 158 session_reset_stream(session); | |
| 159 setup_decompression(session, inflate_stream); | |
| 160 return true; | |
| 161 end; | |
| 162 session:reset_stream(); | |
| 163 local default_stream_attr = {xmlns = "jabber:server", ["xmlns:stream"] = "http://etherx.jabber.org/streams", | |
| 164 version = "1.0", to = session.to_host, from = session.from_host}; | |
| 165 session.sends2s("<?xml version='1.0'?>"); | |
| 166 session.sends2s(st.stanza("stream:stream", default_stream_attr):top_tag()); | |
| 167 session.compressed = true; | |
| 139 end | 168 end |
| 140 ); | 169 ); |
| 141 | 170 |
| 142 module:add_handler({"c2s_unauthed", "c2s", "s2sin_unauthed", "s2sin"}, "compress", xmlns_compression_protocol, | 171 module:add_handler({"c2s_unauthed", "c2s", "s2sin_unauthed", "s2sin"}, "compress", xmlns_compression_protocol, |
| 143 function(session, stanza) | 172 function(session, stanza) |
| 144 -- fail if we are already compressed | 173 -- fail if we are already compressed |
| 145 if session.compressed then | 174 if session.compressed then |
| 146 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); | 175 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); |
| 147 session.send(error_st); | 176 (session.sends2s or session.send)(error_st); |
| 148 session.log("warn", "Tried to establish another compression layer."); | 177 session.log("warn", "Tried to establish another compression layer."); |
| 149 end | 178 end |
| 150 | 179 |
| 151 -- checking if the compression method is supported | 180 -- checking if the compression method is supported |
| 152 local method = stanza:child_with_name("method")[1]; | 181 local method = stanza:child_with_name("method")[1]; |
| 153 if method == "zlib" then | 182 if method == "zlib" then |
| 154 session.log("info", method.." compression selected."); | 183 session.log("info", method.." compression selected."); |
| 155 (session.sends2s or session.send)(st.stanza("compressed", {xmlns=xmlns_compression_protocol})); | |
| 156 session:reset_stream(); | |
| 157 | 184 |
| 158 -- create deflate and inflate streams | 185 -- create deflate and inflate streams |
| 159 deflate_stream = get_deflate_stream(session); | 186 deflate_stream = get_deflate_stream(session); |
| 160 if not deflate_stream then return end | 187 if not deflate_stream then return end |
| 161 | 188 |
| 162 inflate_stream = get_inflate_stream(session); | 189 inflate_stream = get_inflate_stream(session); |
| 163 if not inflate_stream then return end | 190 if not inflate_stream then return end |
| 191 | |
| 192 (session.sends2s or session.send)(st.stanza("compressed", {xmlns=xmlns_compression_protocol})); | |
| 193 session:reset_stream(); | |
| 164 | 194 |
| 165 -- setup compression for session.w | 195 -- setup compression for session.w |
| 166 setup_compression(session, deflate_stream); | 196 setup_compression(session, deflate_stream); |
| 167 | 197 |
| 168 -- setup decompression for session.data | 198 -- setup decompression for session.data |