From: Vsevolod Stakhov Date: Sat, 12 Aug 2017 21:38:25 +0000 (+0100) Subject: [Minor] Make a more universal gzip compress utility X-Git-Tag: 1.7.0~728 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=8189d621e70b4f38abdc6411c3c4ba890ef023f6;p=rspamd.git [Minor] Make a more universal gzip compress utility --- diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c index 77770ae3f..2edaa2612 100644 --- a/src/libserver/worker_util.c +++ b/src/libserver/worker_util.c @@ -370,64 +370,10 @@ static rspamd_fstring_t * rspamd_controller_maybe_compress (struct rspamd_http_connection_entry *entry, rspamd_fstring_t *buf, struct rspamd_http_message *msg) { - z_stream strm; - gint rc; - rspamd_fstring_t *comp; - gchar *p; - gsize remain; - if (entry->support_gzip) { - memset (&strm, 0, sizeof (strm)); - rc = deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, - MAX_WBITS + 16, MAX_MEM_LEVEL - 1, Z_DEFAULT_STRATEGY); - - if (rc != Z_OK) { - return buf; - } - - comp = rspamd_fstring_sized_new (MIN (buf->len, 32768)); - - strm.avail_in = buf->len; - strm.next_in = (guchar *)buf->str; - p = comp->str; - remain = comp->allocated; - - while (strm.avail_in != 0) { - strm.avail_out = remain; - strm.next_out = p; - - rc = deflate (&strm, Z_FINISH); - - if (rc != Z_OK) { - if (rc == Z_STREAM_END) { - break; - } - else { - rspamd_fstring_free (comp); - deflateEnd (&strm); - - return buf; - } - } - - comp->len = strm.total_out; - - if (strm.avail_out == 0 && strm.avail_in != 0) { - /* Need to allocate more */ - remain = comp->len; - comp = rspamd_fstring_grow (comp, comp->allocated + - strm.avail_in + 10); - p = comp->str + remain; - remain = comp->allocated - remain; - } + if (rspamd_fstring_gzip (&buf)) { + rspamd_http_message_add_header (msg, "Content-Encoding", "gzip"); } - - deflateEnd (&strm); - comp->len = strm.total_out; - rspamd_fstring_free (buf); /* We replace buf with its compressed version */ - rspamd_http_message_add_header (msg, "Content-Encoding", "gzip"); - - return comp; } return buf; diff --git a/src/libutil/util.c b/src/libutil/util.c index 54cacef44..fbd1ba823 100644 --- a/src/libutil/util.c +++ b/src/libutil/util.c @@ -1,5 +1,5 @@ /*- - * Copyright 2016 Vsevolod Stakhov + * Copyright 2017 Vsevolod Stakhov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,7 @@ #include /* for pow */ #include "cryptobox.h" +#include "zlib.h" /* Check log messages intensity once per minute */ #define CHECK_TIME 60 @@ -2688,3 +2689,65 @@ rspamd_tm_to_time (const struct tm *tm, glong tz) return result; } + +gboolean +rspamd_fstring_gzip (rspamd_fstring_t **in) +{ + z_stream strm; + gint rc; + rspamd_fstring_t *comp, *buf = *in; + gchar *p; + gsize remain; + + memset (&strm, 0, sizeof (strm)); + rc = deflateInit2 (&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, + MAX_WBITS + 16, MAX_MEM_LEVEL - 1, Z_DEFAULT_STRATEGY); + + if (rc != Z_OK) { + return FALSE; + } + + comp = rspamd_fstring_sized_new (MIN (buf->len, 32768)); + + strm.avail_in = buf->len; + strm.next_in = (guchar *)buf->str; + p = comp->str; + remain = comp->allocated; + + while (strm.avail_in != 0) { + strm.avail_out = remain; + strm.next_out = p; + + rc = deflate (&strm, Z_FINISH); + + if (rc != Z_OK) { + if (rc == Z_STREAM_END) { + break; + } + else { + rspamd_fstring_free (comp); + deflateEnd (&strm); + + return FALSE; + } + } + + comp->len = strm.total_out; + + if (strm.avail_out == 0 && strm.avail_in != 0) { + /* Need to allocate more */ + remain = comp->len; + comp = rspamd_fstring_grow (comp, comp->allocated + + strm.avail_in + 10); + p = comp->str + remain; + remain = comp->allocated - remain; + } + } + + deflateEnd (&strm); + comp->len = strm.total_out; + rspamd_fstring_free (buf); /* We replace buf with its compressed version */ + *in = comp; + + return TRUE; +} \ No newline at end of file diff --git a/src/libutil/util.h b/src/libutil/util.h index 9f42d6c92..d1d83716e 100644 --- a/src/libutil/util.h +++ b/src/libutil/util.h @@ -510,5 +510,12 @@ guint64 rspamd_tm_to_time (const struct tm *tm, glong tz); #define PTR_ARRAY_FOREACH(ar, i, cur) for ((i) = 0; (ar) != NULL && (i) < (ar)->len && (((cur) = g_ptr_array_index((ar), (i))) || 1); ++(i)) +/** + * Compresses the input string using gzip+zlib. Old string is replaced and freed + * if compressed. If not compressed it is untouched. + * @param in + * @return TRUE if a string has been compressed + */ +gboolean rspamd_fstring_gzip (rspamd_fstring_t **in); #endif