Comparison

plugins/mod_compression.lua @ 2280:0b0fe49e5251

Enable one way stream compression on s2s links.
author Tobias Markmann <tm@ayena.de>
date Sun, 29 Nov 2009 21:32:39 +0100
parent 2279:49bc4c7bdef8
child 2282:6f54dac3ec2d
comparison
equal deleted inserted replaced
2279:49bc4c7bdef8 2280:0b0fe49e5251
9 local zlib = require "zlib"; 9 local zlib = require "zlib";
10 local pcall = pcall; 10 local pcall = pcall;
11 11
12 local xmlns_compression_feature = "http://jabber.org/features/compress" 12 local xmlns_compression_feature = "http://jabber.org/features/compress"
13 local xmlns_compression_protocol = "http://jabber.org/protocol/compress" 13 local xmlns_compression_protocol = "http://jabber.org/protocol/compress"
14 local xmlns_stream = "http://etherx.jabber.org/streams";
14 local compression_stream_feature = st.stanza("compression", {xmlns=xmlns_compression_feature}):tag("method"):text("zlib"):up(); 15 local compression_stream_feature = st.stanza("compression", {xmlns=xmlns_compression_feature}):tag("method"):text("zlib"):up();
15 16
16 local compression_level = module:get_option("compression_level"); 17 local compression_level = module:get_option("compression_level");
17 -- if not defined assume admin wants best compression 18 -- if not defined assume admin wants best compression
18 if compression_level == nil then compression_level = 9 end; 19 if compression_level == nil then compression_level = 9 end;
32 features:add_child(compression_stream_feature); 33 features:add_child(compression_stream_feature);
33 end 34 end
34 end 35 end
35 ); 36 );
36 37
38 module:hook("s2s-stream-features",
39 function (data)
40 local session, features = data.session, data.features;
41 -- FIXME only advertise compression support when TLS layer has no compression enabled
42 features:add_child(compression_stream_feature);
43 end
44 );
45
46 -- S2Sout handling aka the client perspective in the S2S connection
47 module:hook_stanza(xmlns_stream, "features",
48 function (session, stanza)
49 if not session.compressed then
50 module:log("debug", "FEATURES: "..stanza:pretty_print())
51 -- does remote server support compression?
52 local comp_st = stanza:child_with_name("compression");
53 if comp_st then
54 -- do we support the mechanism
55 for a in comp_st:children() do
56 local algorithm = a[1]
57 if algorithm == "zlib" then
58 session.sends2s(st.stanza("compress", {xmlns=xmlns_compression_protocol}):text("zlib"))
59 session.log("info", "Enabled compression using zlib.")
60 return true;
61 end
62 end
63 session.log("debug", "Remote server supports no compression algorithm we support.")
64 end
65 end
66 end
67 , 250);
68
37 -- TODO Support compression on S2S level too. 69 -- TODO Support compression on S2S level too.
38 module:add_handler({"c2s_unauthed", "c2s"}, "compress", xmlns_compression_protocol, 70 module:add_handler({"c2s_unauthed", "c2s", "s2sin_unauthed", "s2sin"}, "compress", xmlns_compression_protocol,
39 function(session, stanza) 71 function(session, stanza)
40 -- fail if we are already compressed 72 -- fail if we are already compressed
41 if session.compressed then 73 if session.compressed then
42 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); 74 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method");
43 session.send(error_st); 75 session.send(error_st);
46 78
47 -- checking if the compression method is supported 79 -- checking if the compression method is supported
48 local method = stanza:child_with_name("method")[1]; 80 local method = stanza:child_with_name("method")[1];
49 if method == "zlib" then 81 if method == "zlib" then
50 session.log("info", method.." compression selected."); 82 session.log("info", method.." compression selected.");
51 session.send(st.stanza("compressed", {xmlns=xmlns_compression_protocol})); 83 (session.sends2s or session.send)(st.stanza("compressed", {xmlns=xmlns_compression_protocol}));
52 session:reset_stream(); 84 session:reset_stream();
53 85
54 -- create deflate and inflate streams 86 -- create deflate and inflate streams
55 local status, deflate_stream = pcall(zlib.deflate, compression_level); 87 local status, deflate_stream = pcall(zlib.deflate, compression_level);
56 if status == false then 88 if status == false then
57 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); 89 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed");
58 session.send(error_st); 90 (session.sends2s or session.send)(error_st);
59 session.log("error", "Failed to create zlib.deflate filter."); 91 session.log("error", "Failed to create zlib.deflate filter.");
60 module:log("error", deflate_stream); 92 module:log("error", deflate_stream);
61 return 93 return
62 end 94 end
63 95
64 local status, inflate_stream = pcall(zlib.inflate); 96 local status, inflate_stream = pcall(zlib.inflate);
65 if status == false then 97 if status == false then
66 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); 98 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed");
67 session.send(error_st); 99 (session.sends2s or session.send)(error_st);
68 session.log("error", "Failed to create zlib.deflate filter."); 100 session.log("error", "Failed to create zlib.deflate filter.");
69 module:log("error", inflate_stream); 101 module:log("error", inflate_stream);
70 return 102 return
71 end 103 end
72 104
114 end; 146 end;
115 session.compressed = true; 147 session.compressed = true;
116 else 148 else
117 session.log("info", method.." compression selected. But we don't support it."); 149 session.log("info", method.." compression selected. But we don't support it.");
118 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); 150 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method");
119 session.send(error_st); 151 (session.sends2s or session.send)(error_st);
120 end 152 end
121 end 153 end
122 ); 154 );
155