plugins/mod_compression.lua

changeset 2284
e0b2d934f316
parent 2283
3dd7fdee9035
child 2286
3c17fc919f7b
equal deleted inserted replaced
2283:3dd7fdee9035 2284: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

mercurial