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."); |