Software / code / prosody
Annotate
plugins/mod_compression.lua @ 3027:b5beb7b15ac4
mod_console: Set a chunk name for loadstring calls (nicer errors).
| author | Waqas Hussain <waqas20@gmail.com> |
|---|---|
| date | Fri, 07 May 2010 16:10:04 +0500 |
| parent | 2890:6273d4672cb4 |
| child | 2892:9f214431de29 |
| rev | line source |
|---|---|
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
1 -- Prosody IM |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
2 -- Copyright (C) 2009 Tobias Markmann |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
3 -- |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
4 -- This project is MIT/X11 licensed. Please see the |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
5 -- COPYING file in the source package for more information. |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
6 -- |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
7 |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
8 local st = require "util.stanza"; |
|
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
9 local zlib = require "zlib"; |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
10 local pcall = pcall; |
|
2882
4e72048d4a24
mod_compression: Fixed various possible tracebacks in logging.
Waqas Hussain <waqas20@gmail.com>
parents:
2874
diff
changeset
|
11 local tostring = tostring; |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
12 |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
13 local xmlns_compression_feature = "http://jabber.org/features/compress" |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
14 local xmlns_compression_protocol = "http://jabber.org/protocol/compress" |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
15 local compression_stream_feature = st.stanza("compression", {xmlns=xmlns_compression_feature}):tag("method"):text("zlib"):up(); |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
16 |
| 1676 | 17 local compression_level = module:get_option("compression_level"); |
| 18 -- if not defined assume admin wants best compression | |
| 19 if compression_level == nil then compression_level = 9 end; | |
| 20 | |
| 2874 | 21 |
| 1676 | 22 compression_level = tonumber(compression_level); |
| 23 if not compression_level or compression_level < 1 or compression_level > 9 then | |
| 24 module:log("warn", "Invalid compression level in config: %s", tostring(compression_level)); | |
| 25 module:log("warn", "Module loading aborted. Compression won't be available."); | |
| 26 return; | |
| 27 end | |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
28 |
| 1670 | 29 module:add_event_hook("stream-features", |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
30 function (session, features) |
|
1673
5f81cd6d4a92
Remove space at the end of a line.
Tobias Markmann <tm@ayena.de>
parents:
1672
diff
changeset
|
31 if not session.compressed then |
|
1674
250bddde4162
Add a TODO for s2s compression support.
Tobias Markmann <tm@ayena.de>
parents:
1673
diff
changeset
|
32 -- FIXME only advertise compression support when TLS layer has no compression enabled |
|
1672
614623f393c6
Add FIXME to remember TLS compression detection.
Tobias Markmann <tm@ayena.de>
parents:
1671
diff
changeset
|
33 features:add_child(compression_stream_feature); |
|
614623f393c6
Add FIXME to remember TLS compression detection.
Tobias Markmann <tm@ayena.de>
parents:
1671
diff
changeset
|
34 end |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
35 end |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
36 ); |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
37 |
|
1674
250bddde4162
Add a TODO for s2s compression support.
Tobias Markmann <tm@ayena.de>
parents:
1673
diff
changeset
|
38 -- TODO Support compression on S2S level too. |
|
1728
cb4c94b47d53
mod_compression: Fixed: Starting compression only worked before auth
Waqas Hussain <waqas20@gmail.com>
parents:
1719
diff
changeset
|
39 module:add_handler({"c2s_unauthed", "c2s"}, "compress", xmlns_compression_protocol, |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
40 function(session, stanza) |
|
1719
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
41 -- fail if we are already compressed |
|
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
42 if session.compressed then |
|
2886
3baee526d714
mod_compression: Return <setup-failed/> instead of <unsupported-method/> where applicable.
Waqas Hussain <waqas20@gmail.com>
parents:
2885
diff
changeset
|
43 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); |
|
1719
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
44 session.send(error_st); |
|
2890
6273d4672cb4
mod_compression: Improved and lowered log level of some logged messages.
Waqas Hussain <waqas20@gmail.com>
parents:
2886
diff
changeset
|
45 session.log("debug", "Client tried to establish another compression layer."); |
|
2884
6807f5fa0eb4
mod_compression: Don't succeed after indicating a failure.
Waqas Hussain <waqas20@gmail.com>
parents:
2883
diff
changeset
|
46 return; |
|
1719
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
47 end |
|
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
48 |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
49 -- checking if the compression method is supported |
|
2885
ae72c0dd6f1f
mod_compression: More robust stanza processing.
Waqas Hussain <waqas20@gmail.com>
parents:
2884
diff
changeset
|
50 local method = stanza:child_with_name("method"); |
|
2886
3baee526d714
mod_compression: Return <setup-failed/> instead of <unsupported-method/> where applicable.
Waqas Hussain <waqas20@gmail.com>
parents:
2885
diff
changeset
|
51 method = method and (method[1] or ""); |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
52 if method == "zlib" then |
|
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
53 -- create deflate and inflate streams |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
54 local status, deflate_stream = pcall(zlib.deflate, compression_level); |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
55 if status == false then |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
56 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
57 session.send(error_st); |
| 2874 | 58 session.log("error", "Failed to create zlib.deflate filter."); |
|
2882
4e72048d4a24
mod_compression: Fixed various possible tracebacks in logging.
Waqas Hussain <waqas20@gmail.com>
parents:
2874
diff
changeset
|
59 module:log("error", "%s", tostring(deflate_stream)); |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
60 return |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
61 end |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
62 |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
63 local status, inflate_stream = pcall(zlib.inflate); |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
64 if status == false then |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
65 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
66 session.send(error_st); |
|
2882
4e72048d4a24
mod_compression: Fixed various possible tracebacks in logging.
Waqas Hussain <waqas20@gmail.com>
parents:
2874
diff
changeset
|
67 session.log("error", "Failed to create zlib.inflate filter."); |
|
4e72048d4a24
mod_compression: Fixed various possible tracebacks in logging.
Waqas Hussain <waqas20@gmail.com>
parents:
2874
diff
changeset
|
68 module:log("error", "%s", tostring(inflate_stream)); |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
69 return |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
70 end |
|
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
71 |
|
2890
6273d4672cb4
mod_compression: Improved and lowered log level of some logged messages.
Waqas Hussain <waqas20@gmail.com>
parents:
2886
diff
changeset
|
72 session.log("debug", "zlib compression enabled."); |
|
2883
adbca5af8536
mod_compression: Don't tell client compression succeeded when it didn't.
Waqas Hussain <waqas20@gmail.com>
parents:
2882
diff
changeset
|
73 session.send(st.stanza("compressed", {xmlns=xmlns_compression_protocol})); |
|
adbca5af8536
mod_compression: Don't tell client compression succeeded when it didn't.
Waqas Hussain <waqas20@gmail.com>
parents:
2882
diff
changeset
|
74 session:reset_stream(); |
|
adbca5af8536
mod_compression: Don't tell client compression succeeded when it didn't.
Waqas Hussain <waqas20@gmail.com>
parents:
2882
diff
changeset
|
75 |
|
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
76 -- setup compression for session.w |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
77 local old_send = session.send; |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
78 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
79 session.send = function(t) |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
80 local status, compressed, eof = pcall(deflate_stream, tostring(t), 'sync'); |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
81 if status == false then |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
82 session:close({ |
|
1718
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
83 condition = "undefined-condition"; |
|
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
84 text = compressed; |
|
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
85 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed"); |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
86 }); |
|
2882
4e72048d4a24
mod_compression: Fixed various possible tracebacks in logging.
Waqas Hussain <waqas20@gmail.com>
parents:
2874
diff
changeset
|
87 module:log("warn", "%s", tostring(compressed)); |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
88 return; |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
89 end |
|
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
90 old_send(compressed); |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
91 end; |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
92 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
93 -- setup decompression for session.data |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
94 local function setup_decompression(session) |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
95 local old_data = session.data |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
96 session.data = function(conn, data) |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
97 local status, decompressed, eof = pcall(inflate_stream, data); |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
98 if status == false then |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
99 session:close({ |
|
1718
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
100 condition = "undefined-condition"; |
|
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
101 text = decompressed; |
|
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
102 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed"); |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
103 }); |
|
2882
4e72048d4a24
mod_compression: Fixed various possible tracebacks in logging.
Waqas Hussain <waqas20@gmail.com>
parents:
2874
diff
changeset
|
104 module:log("warn", "%s", tostring(decompressed)); |
|
1678
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
105 return; |
|
79eb903d0e67
Using pcall to make save the rest from zlib fails. Emit errors on those fails.
Tobias Markmann <tm@ayena.de>
parents:
1677
diff
changeset
|
106 end |
|
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
107 old_data(conn, decompressed); |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
108 end; |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
109 end |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
110 setup_decompression(session); |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
111 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
112 local session_reset_stream = session.reset_stream; |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
113 session.reset_stream = function(session) |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
114 session_reset_stream(session); |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
115 setup_decompression(session); |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
116 return true; |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
117 end; |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
118 session.compressed = true; |
|
2886
3baee526d714
mod_compression: Return <setup-failed/> instead of <unsupported-method/> where applicable.
Waqas Hussain <waqas20@gmail.com>
parents:
2885
diff
changeset
|
119 elseif method then |
|
2890
6273d4672cb4
mod_compression: Improved and lowered log level of some logged messages.
Waqas Hussain <waqas20@gmail.com>
parents:
2886
diff
changeset
|
120 session.log("debug", "%s compression selected, but we don't support it.", tostring(method)); |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
121 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
122 session.send(error_st); |
|
2886
3baee526d714
mod_compression: Return <setup-failed/> instead of <unsupported-method/> where applicable.
Waqas Hussain <waqas20@gmail.com>
parents:
2885
diff
changeset
|
123 else |
|
3baee526d714
mod_compression: Return <setup-failed/> instead of <unsupported-method/> where applicable.
Waqas Hussain <waqas20@gmail.com>
parents:
2885
diff
changeset
|
124 session.send(st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed")); |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
125 end |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
126 end |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
127 ); |