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 |