Browse Source

[Feature] Add gzip compression support for rspamd controller

tags/1.7.0
Vsevolod Stakhov 6 years ago
parent
commit
eaddd22640
4 changed files with 85 additions and 9 deletions
  1. 2
    3
      CMakeLists.txt
  2. 74
    6
      src/libserver/worker_util.c
  3. 8
    0
      src/libutil/http.c
  4. 1
    0
      src/libutil/http.h

+ 2
- 3
CMakeLists.txt View File

LIST(APPEND CMAKE_REQUIRED_LIBRARIES resolv) LIST(APPEND CMAKE_REQUIRED_LIBRARIES resolv)
LIST(APPEND CMAKE_REQUIRED_LIBRARIES nsl) LIST(APPEND CMAKE_REQUIRED_LIBRARIES nsl)
MESSAGE(STATUS "Configuring for Linux") MESSAGE(STATUS "Configuring for Linux")
IF(ENABLE_STATIC MATCHES "ON")
LIST(APPEND CMAKE_REQUIRED_LIBRARIES z)
ENDIF()
IF(EXISTS "/etc/debian_version") IF(EXISTS "/etc/debian_version")
SET(LINUX_START_SCRIPT "rspamd_debian.in") SET(LINUX_START_SCRIPT "rspamd_debian.in")
ELSE(EXISTS "/etc/debian_version") ELSE(EXISTS "/etc/debian_version")
ROOT ${OPENSSL_ROOT_DIR} MODULES openssl libssl) ROOT ${OPENSSL_ROOT_DIR} MODULES openssl libssl)
ProcessPackage(MAGIC LIBRARY magic INCLUDE magic.h INCLUDE_SUFFIXES include/libmagic ProcessPackage(MAGIC LIBRARY magic INCLUDE magic.h INCLUDE_SUFFIXES include/libmagic
ROOT ${LIBMAGIC_ROOT_DIR} MODULES magic) ROOT ${LIBMAGIC_ROOT_DIR} MODULES magic)
ProcessPackage(LIBZ LIBRARY z INCLUDE zlib.h INCLUDE_SUFFIXES include/zlib
ROOT ${LIBZ_ROOT_DIR} MODULES z)


IF(ENABLE_HYPERSCAN MATCHES "ON") IF(ENABLE_HYPERSCAN MATCHES "ON")
ProcessPackage(HYPERSCAN LIBRARY hs INCLUDE hs.h INCLUDE_SUFFIXES ProcessPackage(HYPERSCAN LIBRARY hs INCLUDE hs.h INCLUDE_SUFFIXES

+ 74
- 6
src/libserver/worker_util.c View File

#ifdef HAVE_LIBUTIL_H #ifdef HAVE_LIBUTIL_H
#include <libutil.h> #include <libutil.h>
#endif #endif
#include "zlib.h"


static void rspamd_worker_ignore_signal (int signo); static void rspamd_worker_ignore_signal (int signo);
/** /**
{ {
GList *cur; GList *cur;
struct event *events; struct event *events;
GHashTableIter it;
struct rspamd_worker_signal_handler *sigh;
gpointer k, v;
struct rspamd_map *map; struct rspamd_map *map;


/* Remove all events */ /* Remove all events */
} }
} }


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;
}
}

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;
}

void void
rspamd_controller_send_error (struct rspamd_http_connection_entry *entry, rspamd_controller_send_error (struct rspamd_http_connection_entry *entry,
gint code, const gchar *error_msg, ...) gint code, const gchar *error_msg, ...)
msg->code = code; msg->code = code;
reply = rspamd_fstring_sized_new (msg->status->len + 16); reply = rspamd_fstring_sized_new (msg->status->len + 16);
rspamd_printf_fstring (&reply, "{\"error\":\"%V\"}", msg->status); rspamd_printf_fstring (&reply, "{\"error\":\"%V\"}", msg->status);
rspamd_http_message_set_body_from_fstring_steal (msg, reply);
rspamd_http_message_set_body_from_fstring_steal (msg,
rspamd_controller_maybe_compress (entry, reply, msg));
rspamd_http_connection_reset (entry->conn); rspamd_http_connection_reset (entry->conn);
rspamd_http_router_insert_headers (entry->rt, msg); rspamd_http_router_insert_headers (entry->rt, msg);
rspamd_http_connection_write_message (entry->conn, rspamd_http_connection_write_message (entry->conn,
msg->code = 200; msg->code = 200;
msg->status = rspamd_fstring_new_init ("OK", 2); msg->status = rspamd_fstring_new_init ("OK", 2);
reply = rspamd_fstring_new_init (str, strlen (str)); reply = rspamd_fstring_new_init (str, strlen (str));
rspamd_http_message_set_body_from_fstring_steal (msg, reply);
rspamd_http_message_set_body_from_fstring_steal (msg,
rspamd_controller_maybe_compress (entry, reply, msg));
rspamd_http_connection_reset (entry->conn); rspamd_http_connection_reset (entry->conn);
rspamd_http_router_insert_headers (entry->rt, msg); rspamd_http_router_insert_headers (entry->rt, msg);
rspamd_http_connection_write_message (entry->conn, rspamd_http_connection_write_message (entry->conn,
msg->status = rspamd_fstring_new_init ("OK", 2); msg->status = rspamd_fstring_new_init ("OK", 2);
reply = rspamd_fstring_sized_new (BUFSIZ); reply = rspamd_fstring_sized_new (BUFSIZ);
rspamd_ucl_emit_fstring (obj, UCL_EMIT_JSON_COMPACT, &reply); rspamd_ucl_emit_fstring (obj, UCL_EMIT_JSON_COMPACT, &reply);
rspamd_http_message_set_body_from_fstring_steal (msg, reply);
rspamd_http_message_set_body_from_fstring_steal (msg,
rspamd_controller_maybe_compress (entry, reply, msg));
rspamd_http_connection_reset (entry->conn); rspamd_http_connection_reset (entry->conn);
rspamd_http_router_insert_headers (entry->rt, msg); rspamd_http_router_insert_headers (entry->rt, msg);
rspamd_http_connection_write_message (entry->conn, rspamd_http_connection_write_message (entry->conn,

+ 8
- 0
src/libutil/http.c View File



GError *err; GError *err;
rspamd_ftok_t lookup; rspamd_ftok_t lookup;
const rspamd_ftok_t *encoding;
struct http_parser_url u; struct http_parser_url u;
guint i; guint i;
rspamd_regexp_t *re; rspamd_regexp_t *re;


entry->is_reply = TRUE; entry->is_reply = TRUE;


encoding = rspamd_http_message_find_header (msg, "Accept-Encoding");

if (encoding && rspamd_substring_search (encoding->begin, encoding->len,
"gzip", 4) != -1) {
entry->support_gzip = TRUE;
}

if (handler != NULL) { if (handler != NULL) {
return handler (entry, msg); return handler (entry, msg);
} }

+ 1
- 0
src/libutil/http.h View File

struct rspamd_http_connection *conn; struct rspamd_http_connection *conn;
gpointer ud; gpointer ud;
gboolean is_reply; gboolean is_reply;
gboolean support_gzip;
struct rspamd_http_connection_entry *prev, *next; struct rspamd_http_connection_entry *prev, *next;
}; };



Loading…
Cancel
Save