Mercurial > prosody-hg
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 |
| parents | 49bc4c7bdef8 |
| children | 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 |
