plugins/mod_compression.lua

changeset 2283
3dd7fdee9035
parent 2282
491b89d6816b
child 2284
e0b2d934f316
equal deleted inserted replaced
2282:491b89d6816b 2283:3dd7fdee9035
63 end 63 end
64 end 64 end
65 end 65 end
66 , 250); 66 , 250);
67 67
68
69 -- returns either nil or a fully functional ready to use inflate stream
70 local function get_deflate_stream(session)
71 local status, deflate_stream = pcall(zlib.deflate, compression_level);
72 if status == false then
73 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed");
74 (session.sends2s or session.send)(error_st);
75 session.log("error", "Failed to create zlib.deflate filter.");
76 module:log("error", deflate_stream);
77 return
78 end
79 return deflate_stream
80 end
81
82 -- returns either nil or a fully functional ready to use inflate stream
83 local function get_inflate_stream(session)
84 local status, inflate_stream = pcall(zlib.inflate);
85 if status == false then
86 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed");
87 (session.sends2s or session.send)(error_st);
88 session.log("error", "Failed to create zlib.deflate filter.");
89 module:log("error", inflate_stream);
90 return
91 end
92 return inflate_stream
93 end
94
95 -- setup compression for a stream
96 local function setup_compression(session, deflate_stream)
97 local old_send = (session.sends2s or session.send);
98
99 local new_send = function(t)
100 local status, compressed, eof = pcall(deflate_stream, tostring(t), 'sync');
101 if status == false then
102 session:close({
103 condition = "undefined-condition";
104 text = compressed;
105 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed");
106 });
107 module:log("warn", compressed);
108 return;
109 end
110 old_send(compressed);
111 end;
112
113 if session.sends2s then session.sends2s = new_send
114 elseif session.send then session.send = new_send end
115 end
116
117 -- setup decompression for a stream
118 local function setup_decompression(session, inflate_stream)
119 local old_data = session.data
120 session.data = function(conn, data)
121 local status, decompressed, eof = pcall(inflate_stream, data);
122 if status == false then
123 session:close({
124 condition = "undefined-condition";
125 text = decompressed;
126 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed");
127 });
128 module:log("warn", decompressed);
129 return;
130 end
131 old_data(conn, decompressed);
132 end;
133 end
134
68 -- TODO Support compression on S2S level too. 135 -- TODO Support compression on S2S level too.
69 module:add_handler({"s2sout_unauthed", "s2sout"}, "compressed", xmlns_compression_protocol, 136 module:add_handler({"s2sout_unauthed", "s2sout"}, "compressed", xmlns_compression_protocol,
70 function(session ,stanza) 137 function(session ,stanza)
71 session.log("debug", "Activating compression...") 138 session.log("debug", "Activating compression...")
72 end 139 end
87 session.log("info", method.." compression selected."); 154 session.log("info", method.." compression selected.");
88 (session.sends2s or session.send)(st.stanza("compressed", {xmlns=xmlns_compression_protocol})); 155 (session.sends2s or session.send)(st.stanza("compressed", {xmlns=xmlns_compression_protocol}));
89 session:reset_stream(); 156 session:reset_stream();
90 157
91 -- create deflate and inflate streams 158 -- create deflate and inflate streams
92 local status, deflate_stream = pcall(zlib.deflate, compression_level); 159 deflate_stream = get_deflate_stream(session);
93 if status == false then 160 if not deflate_stream then return end
94 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed");
95 (session.sends2s or session.send)(error_st);
96 session.log("error", "Failed to create zlib.deflate filter.");
97 module:log("error", deflate_stream);
98 return
99 end
100 161
101 local status, inflate_stream = pcall(zlib.inflate); 162 inflate_stream = get_inflate_stream(session);
102 if status == false then 163 if not inflate_stream then return end
103 local error_st = st.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed");
104 (session.sends2s or session.send)(error_st);
105 session.log("error", "Failed to create zlib.deflate filter.");
106 module:log("error", inflate_stream);
107 return
108 end
109 164
110 -- setup compression for session.w 165 -- setup compression for session.w
111 local function setup_compression(session) 166 setup_compression(session, deflate_stream);
112 local old_send = (session.sends2s or session.send);
113
114 local new_send = function(t)
115 local status, compressed, eof = pcall(deflate_stream, tostring(t), 'sync');
116 if status == false then
117 session:close({
118 condition = "undefined-condition";
119 text = compressed;
120 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed");
121 });
122 module:log("warn", compressed);
123 return;
124 end
125 old_send(compressed);
126 end;
127
128 if session.sends2s then session.sends2s = new_send
129 elseif session.send then session.send = new_send end
130 end
131 setup_compression(session);
132 167
133 -- setup decompression for session.data 168 -- setup decompression for session.data
134 local function setup_decompression(session) 169 setup_decompression(session, inflate_stream);
135 local old_data = session.data
136 session.data = function(conn, data)
137 local status, decompressed, eof = pcall(inflate_stream, data);
138 if status == false then
139 session:close({
140 condition = "undefined-condition";
141 text = decompressed;
142 extra = st.stanza("failure", {xmlns="http://jabber.org/protocol/compress"}):tag("processing-failed");
143 });
144 module:log("warn", decompressed);
145 return;
146 end
147 old_data(conn, decompressed);
148 end;
149 end
150 setup_decompression(session);
151 170
152 local session_reset_stream = session.reset_stream; 171 local session_reset_stream = session.reset_stream;
153 session.reset_stream = function(session) 172 session.reset_stream = function(session)
154 session_reset_stream(session); 173 session_reset_stream(session);
155 setup_decompression(session); 174 setup_decompression(session, inflate_stream);
156 return true; 175 return true;
157 end; 176 end;
158 session.compressed = true; 177 session.compressed = true;
159 else 178 else
160 session.log("info", method.." compression selected. But we don't support it."); 179 session.log("info", method.." compression selected. But we don't support it.");

mercurial