]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
doveadm zlibconnect: Support multiple compression algorithms
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 27 Jan 2021 18:26:26 +0000 (20:26 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 23 Mar 2021 10:13:23 +0000 (10:13 +0000)
Unfortunately they don't work very well, because only the deflate ostream
supports flushing ostream before closing it.

src/doveadm/doveadm-zlib.c

index d22008a88b621000dd5e893d39309288b6735c2d..02d100af8647fefbd6b81fa16c5b003978363e55 100644 (file)
@@ -8,6 +8,7 @@
 #include "ostream-zlib.h"
 #include "module-dir.h"
 #include "master-service.h"
+#include "compression.h"
 #include "doveadm-dump.h"
 
 #include <stdio.h>
@@ -87,16 +88,25 @@ struct client {
        struct io *io_client, *io_server;
        struct istream *input, *stdin_input;
        struct ostream *output;
+       const struct compression_handler *handler;
+       char *algorithm;
        bool compressed;
        bool compress_waiting;
 };
 
-static bool client_input_is_compress_command(const char *line)
+static bool
+client_input_get_compress_algorithm(struct client *client, const char *line)
 {
        /* skip tag */
        while (*line != ' ' && *line != '\0')
                line++;
-       return strcasecmp(line, " COMPRESS DEFLATE") == 0;
+       if (strncasecmp(line, " COMPRESS ", 10) != 0)
+               return FALSE;
+
+       if (compression_lookup_handler(t_str_lcase(line+10),
+                                      &client->handler) <= 0)
+               i_fatal("Unsupported compression mechanism: %s", line+10);
+       return TRUE;
 }
 
 static bool client_input_uncompressed(struct client *client)
@@ -112,7 +122,7 @@ static bool client_input_uncompressed(struct client *client)
        while ((line = i_stream_read_next_line(client->stdin_input)) != NULL) {
                o_stream_nsend_str(client->output, line);
                o_stream_nsend(client->output, "\n", 1);
-               if (client_input_is_compress_command(line))
+               if (client_input_get_compress_algorithm(client, line))
                        return TRUE;
        }
        return FALSE;
@@ -134,6 +144,10 @@ static void client_input(struct client *client)
                        o_stream_nsend(client->output, data, size);
                        i_stream_skip(client->stdin_input, size);
                }
+               if (o_stream_flush(client->output) < 0) {
+                       i_fatal("write() failed: %s",
+                               o_stream_get_error(client->output));
+               }
        }
        if (client->stdin_input->eof) {
                if (client->stdin_input->stream_errno != 0) {
@@ -189,8 +203,8 @@ static void server_input(struct client *client)
                struct ostream *output;
 
                i_info("<Compression started>");
-               input = i_stream_create_deflate(client->input);
-               output = o_stream_create_deflate(client->output, 6);
+               input = client->handler->create_istream(client->input);
+               output = client->handler->create_ostream(client->output, 6);
                i_stream_unref(&client->input);
                o_stream_unref(&client->output);
                client->input = input;