author | Waqas Hussain <waqas20@gmail.com> |
Wed, 02 Sep 2009 19:22:06 +0500 | |
changeset 1728 | cb4c94b47d53 |
parent 1719 | cf103398e643 |
child 2279 | 49bc4c7bdef8 |
permissions | -rw-r--r-- |
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; |
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
11 |
|
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
12 |
local xmlns_compression_feature = "http://jabber.org/features/compress" |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
13 |
local xmlns_compression_protocol = "http://jabber.org/protocol/compress" |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
14 |
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
|
15 |
|
1676 | 16 |
local compression_level = module:get_option("compression_level"); |
17 |
||
18 |
-- if not defined assume admin wants best compression |
|
19 |
if compression_level == nil then compression_level = 9 end; |
|
20 |
||
21 |
compression_level = tonumber(compression_level); |
|
22 |
if not compression_level or compression_level < 1 or compression_level > 9 then |
|
23 |
module:log("warn", "Invalid compression level in config: %s", tostring(compression_level)); |
|
24 |
module:log("warn", "Module loading aborted. Compression won't be available."); |
|
25 |
return; |
|
26 |
end |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
27 |
|
1670 | 28 |
module:add_event_hook("stream-features", |
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
29 |
function (session, features) |
1673
5f81cd6d4a92
Remove space at the end of a line.
Tobias Markmann <tm@ayena.de>
parents:
1672
diff
changeset
|
30 |
if not session.compressed then |
1674
250bddde4162
Add a TODO for s2s compression support.
Tobias Markmann <tm@ayena.de>
parents:
1673
diff
changeset
|
31 |
-- 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
|
32 |
features:add_child(compression_stream_feature); |
614623f393c6
Add FIXME to remember TLS compression detection.
Tobias Markmann <tm@ayena.de>
parents:
1671
diff
changeset
|
33 |
end |
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
34 |
end |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
35 |
); |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
36 |
|
1674
250bddde4162
Add a TODO for s2s compression support.
Tobias Markmann <tm@ayena.de>
parents:
1673
diff
changeset
|
37 |
-- 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
|
38 |
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
|
39 |
function(session, stanza) |
1719
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
40 |
-- fail if we are already compressed |
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
41 |
if session.compressed then |
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
42 |
local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("unsupported-method"); |
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
43 |
session.send(error_st); |
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
44 |
session:log("warn", "Tried to establish another compression layer."); |
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
45 |
end |
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
46 |
|
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
47 |
-- checking if the compression method is supported |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
48 |
local method = stanza:child_with_name("method")[1]; |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
49 |
if method == "zlib" then |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
50 |
session.log("info", method.." compression selected."); |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
51 |
session.send(st.stanza("compressed", {xmlns=xmlns_compression_protocol})); |
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
52 |
session:reset_stream(); |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
53 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
54 |
-- 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
|
55 |
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
|
56 |
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
|
57 |
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
|
58 |
session.send(error_st); |
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
|
59 |
session:log("error", "Failed to create zlib.deflate filter."); |
1716
3f7fd1445d02
mod_compression: Fixed some undefined global accesses
Waqas Hussain <waqas20@gmail.com>
parents:
1679
diff
changeset
|
60 |
module:log("error", 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
|
61 |
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
|
62 |
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
|
63 |
|
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 |
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
|
65 |
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
|
66 |
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
|
67 |
session.send(error_st); |
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
|
68 |
session:log("error", "Failed to create zlib.deflate filter."); |
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 |
module:log("error", inflate_stream); |
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 |
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
|
71 |
end |
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
72 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
73 |
-- 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
|
74 |
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
|
75 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
76 |
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
|
77 |
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
|
78 |
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
|
79 |
session:close({ |
1718
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
80 |
condition = "undefined-condition"; |
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
81 |
text = compressed; |
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
82 |
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
|
83 |
}); |
1719
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
84 |
module:log("warn", 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
|
85 |
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
|
86 |
end |
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
87 |
old_send(compressed); |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
88 |
end; |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
89 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
90 |
-- 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
|
91 |
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
|
92 |
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
|
93 |
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
|
94 |
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
|
95 |
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
|
96 |
session:close({ |
1718
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
97 |
condition = "undefined-condition"; |
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
98 |
text = decompressed; |
af3d0c329396
Support compression also after SASL.
Tobias Markmann <tm@ayena.de>
parents:
1716
diff
changeset
|
99 |
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
|
100 |
}); |
1719
cf103398e643
Don't allow double compression.
Tobias Markmann <tm@ayena.de>
parents:
1718
diff
changeset
|
101 |
module:log("warn", 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
|
102 |
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
|
103 |
end |
1671
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
104 |
old_data(conn, decompressed); |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
105 |
end; |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
106 |
end |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
107 |
setup_decompression(session); |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
108 |
|
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
109 |
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
|
110 |
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
|
111 |
session_reset_stream(session); |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
112 |
setup_decompression(session); |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
113 |
return true; |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
114 |
end; |
d196ac213104
Actually inject de- and compression into the reading/writing functions.
Tobias Markmann <tm@ayena.de>
parents:
1670
diff
changeset
|
115 |
session.compressed = true; |
1669
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
116 |
else |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
117 |
session.log("info", method.." compression selected. But we don't support it."); |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
118 |
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
|
119 |
session.send(error_st); |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
120 |
end |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
121 |
end |
b8eec163a823
Commit initial version of mod_compression.
Tobias Markmann <tm@ayena.de>
parents:
diff
changeset
|
122 |
); |