Software /
code /
verse
File
plugins/compression.lua @ 498:50d0bd035bb7
util.sasl.oauthbearer: Don't send authzid
It's not needed and not recommended in XMPP unless we want to act as
someone other than who we authenticate as. We find out the JID during
resource binding.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Fri, 23 Jun 2023 12:09:49 +0200 |
parent | 380:0891b4e27766 |
line wrap: on
line source
-- Copyright (C) 2009-2010 Matthew Wild -- Copyright (C) 2009-2010 Tobias Markmann -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- local verse = require "verse"; local zlib = require "zlib"; local xmlns_compression_feature = "http://jabber.org/features/compress" local xmlns_compression_protocol = "http://jabber.org/protocol/compress" local xmlns_stream = "http://etherx.jabber.org/streams"; local compression_level = 9; -- returns either nil or a fully functional ready to use inflate stream local function get_deflate_stream(session) local status, deflate_stream = pcall(zlib.deflate, compression_level); if status == false then local error_st = verse.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); session:send(error_st); session:error("Failed to create zlib.deflate filter: %s", tostring(deflate_stream)); return end return deflate_stream end -- returns either nil or a fully functional ready to use inflate stream local function get_inflate_stream(session) local status, inflate_stream = pcall(zlib.inflate); if status == false then local error_st = verse.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("setup-failed"); session:send(error_st); session:error("Failed to create zlib.inflate filter: %s", tostring(inflate_stream)); return end return inflate_stream end -- setup compression for a stream local function setup_compression(session, deflate_stream) function session:send(t) --TODO: Better code injection in the sending process local status, compressed, eof = pcall(deflate_stream, tostring(t), 'sync'); if status == false then session:close({ condition = "undefined-condition"; text = compressed; extra = verse.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("processing-failed"); }); session:warn("Compressed send failed: %s", tostring(compressed)); return; end session.conn:write(compressed); end; end -- setup decompression for a stream local function setup_decompression(session, inflate_stream) local old_data = session.data session.data = function(conn, data) session:debug("Decompressing data..."); local status, decompressed, eof = pcall(inflate_stream, data); if status == false then session:close({ condition = "undefined-condition"; text = decompressed; extra = verse.stanza("failure", {xmlns=xmlns_compression_protocol}):tag("processing-failed"); }); stream:warn("%s", tostring(decompressed)); return; end return old_data(conn, decompressed); end; end function verse.plugins.compression(stream) local function handle_features(features) if not stream.compressed then -- does remote server support compression? local comp_st = features:child_with_name("compression"); if comp_st then -- do we support the mechanism for a in comp_st:children() do local algorithm = a[1] if algorithm == "zlib" then stream:send(verse.stanza("compress", {xmlns=xmlns_compression_protocol}):tag("method"):text("zlib")) stream:debug("Enabled compression using zlib.") return true; end end session:debug("Remote server supports no compression algorithm we support.") end end end local function handle_compressed(stanza) if stanza.name == "compressed" then stream:debug("Activating compression...") -- create deflate and inflate streams local deflate_stream = get_deflate_stream(stream); if not deflate_stream then return end local inflate_stream = get_inflate_stream(stream); if not inflate_stream then return end -- setup compression for stream.w setup_compression(stream, deflate_stream); -- setup decompression for stream.data setup_decompression(stream, inflate_stream); stream.compressed = true; stream:reopen(); elseif stanza.name == "failure" then stream:warn("Failed to establish compression"); end end stream:hook("stream-features", handle_features, 250); stream:hook("stream/"..xmlns_compression_protocol, handle_compressed); end