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 |