commit 5fe4378: [Project] Adopt librspamdserver for http context
Vsevolod Stakhov
vsevolod at highsecure.ru
Tue Feb 19 18:00:08 UTC 2019
Author: Vsevolod Stakhov
Date: 2019-02-19 17:56:42 +0000
URL: https://github.com/rspamd/rspamd/commit/5fe437851dc63bf9c7488d34e434b0e00fd2656a
[Project] Adopt librspamdserver for http context
---
src/libserver/rspamd_control.c | 7 +-
src/libutil/CMakeLists.txt | 1 +
src/libutil/http_connection.c | 310 +++++------------------------------------
src/libutil/http_connection.h | 9 +-
src/libutil/http_private.h | 13 ++
src/libutil/http_router.c | 18 +--
src/libutil/http_router.h | 5 +-
src/libutil/http_util.c | 266 +++++++++++++++++++++++++++++++++++
src/libutil/map.c | 13 +-
src/libutil/util.c | 152 ++++++++++++--------
src/libutil/util.h | 3 +
11 files changed, 431 insertions(+), 366 deletions(-)
diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c
index 2fd1d983f..fb0fc22b6 100644
--- a/src/libserver/rspamd_control.c
+++ b/src/libserver/rspamd_control.c
@@ -511,13 +511,12 @@ rspamd_control_process_client_socket (struct rspamd_main *rspamd_main,
session = g_malloc0 (sizeof (*session));
session->fd = fd;
- session->conn = rspamd_http_connection_new (NULL,
+ session->conn = rspamd_http_connection_new (rspamd_main->http_ctx,
+ NULL,
rspamd_control_error_handler,
rspamd_control_finish_handler,
0,
- RSPAMD_HTTP_SERVER,
- NULL,
- NULL);
+ RSPAMD_HTTP_SERVER);
session->rspamd_main = rspamd_main;
rspamd_http_connection_read_message (session->conn, session, session->fd,
&io_timeout, rspamd_main->ev_base);
diff --git a/src/libutil/CMakeLists.txt b/src/libutil/CMakeLists.txt
index 4d4f8c7bd..f86d650f0 100644
--- a/src/libutil/CMakeLists.txt
+++ b/src/libutil/CMakeLists.txt
@@ -10,6 +10,7 @@ SET(LIBRSPAMDUTILSRC
${CMAKE_CURRENT_SOURCE_DIR}/http_message.c
${CMAKE_CURRENT_SOURCE_DIR}/http_connection.c
${CMAKE_CURRENT_SOURCE_DIR}/http_router.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/http_context.c
${CMAKE_CURRENT_SOURCE_DIR}/logger.c
${CMAKE_CURRENT_SOURCE_DIR}/map.c
${CMAKE_CURRENT_SOURCE_DIR}/map_helpers.c
diff --git a/src/libutil/http_connection.c b/src/libutil/http_connection.c
index df283f752..8463ff762 100644
--- a/src/libutil/http_connection.c
+++ b/src/libutil/http_connection.c
@@ -55,9 +55,10 @@ enum rspamd_http_priv_flags {
#define IS_CONN_RESETED(c) ((c)->flags & RSPAMD_HTTP_CONN_FLAG_RESETED)
struct rspamd_http_connection_private {
- gpointer ssl_ctx;
+ struct rspamd_http_context *ctx;
struct rspamd_ssl_connection *ssl;
struct _rspamd_http_privbuf *buf;
+ struct rspamd_keypair_cache *cache;
struct rspamd_cryptobox_pubkey *peer_key;
struct rspamd_cryptobox_keypair *local_key;
struct rspamd_http_header *header;
@@ -133,272 +134,6 @@ rspamd_http_code_to_str (gint code)
return "Unknown error";
}
-/*
- * Obtained from nginx
- * Copyright (C) Igor Sysoev
- */
-static guint mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-time_t
-rspamd_http_parse_date (const gchar *header, gsize len)
-{
- const gchar *p, *end;
- gint month;
- guint day, year, hour, min, sec;
- guint64 time;
- enum {
- no = 0, rfc822, /* Tue, 10 Nov 2002 23:50:13 */
- rfc850, /* Tuesday, 10-Dec-02 23:50:13 */
- isoc /* Tue Dec 10 23:50:13 2002 */
- } fmt;
-
- fmt = 0;
- if (len > 0) {
- end = header + len;
- }
- else {
- end = header + strlen (header);
- }
-
- day = 32;
- year = 2038;
-
- for (p = header; p < end; p++) {
- if (*p == ',') {
- break;
- }
-
- if (*p == ' ') {
- fmt = isoc;
- break;
- }
- }
-
- for (p++; p < end; p++)
- if (*p != ' ') {
- break;
- }
-
- if (end - p < 18) {
- return (time_t)-1;
- }
-
- if (fmt != isoc) {
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return (time_t)-1;
- }
-
- day = (*p - '0') * 10 + *(p + 1) - '0';
- p += 2;
-
- if (*p == ' ') {
- if (end - p < 18) {
- return (time_t)-1;
- }
- fmt = rfc822;
-
- }
- else if (*p == '-') {
- fmt = rfc850;
-
- }
- else {
- return (time_t)-1;
- }
-
- p++;
- }
-
- switch (*p) {
-
- case 'J':
- month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
- break;
-
- case 'F':
- month = 1;
- break;
-
- case 'M':
- month = *(p + 2) == 'r' ? 2 : 4;
- break;
-
- case 'A':
- month = *(p + 1) == 'p' ? 3 : 7;
- break;
-
- case 'S':
- month = 8;
- break;
-
- case 'O':
- month = 9;
- break;
-
- case 'N':
- month = 10;
- break;
-
- case 'D':
- month = 11;
- break;
-
- default:
- return (time_t)-1;
- }
-
- p += 3;
-
- if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
- return (time_t)-1;
- }
-
- p++;
-
- if (fmt == rfc822) {
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
- || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0'
- || *(p + 3) > '9') {
- return (time_t)-1;
- }
-
- year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
- + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
- p += 4;
-
- }
- else if (fmt == rfc850) {
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return (time_t)-1;
- }
-
- year = (*p - '0') * 10 + *(p + 1) - '0';
- year += (year < 70) ? 2000 : 1900;
- p += 2;
- }
-
- if (fmt == isoc) {
- if (*p == ' ') {
- p++;
- }
-
- if (*p < '0' || *p > '9') {
- return (time_t)-1;
- }
-
- day = *p++ - '0';
-
- if (*p != ' ') {
- if (*p < '0' || *p > '9') {
- return (time_t)-1;
- }
-
- day = day * 10 + *p++ - '0';
- }
-
- if (end - p < 14) {
- return (time_t)-1;
- }
- }
-
- if (*p++ != ' ') {
- return (time_t)-1;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return (time_t)-1;
- }
-
- hour = (*p - '0') * 10 + *(p + 1) - '0';
- p += 2;
-
- if (*p++ != ':') {
- return (time_t)-1;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return (time_t)-1;
- }
-
- min = (*p - '0') * 10 + *(p + 1) - '0';
- p += 2;
-
- if (*p++ != ':') {
- return (time_t)-1;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
- return (time_t)-1;
- }
-
- sec = (*p - '0') * 10 + *(p + 1) - '0';
-
- if (fmt == isoc) {
- p += 2;
-
- if (*p++ != ' ') {
- return (time_t)-1;
- }
-
- if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
- || *(p + 2) < '0' || *(p + 2) > '9' || *(p + 3) < '0'
- || *(p + 3) > '9') {
- return (time_t)-1;
- }
-
- year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
- + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
- }
-
- if (hour > 23 || min > 59 || sec > 59) {
- return (time_t)-1;
- }
-
- if (day == 29 && month == 1) {
- if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
- return (time_t)-1;
- }
-
- }
- else if (day > mday[month]) {
- return (time_t)-1;
- }
-
- /*
- * shift new year to March 1 and start months from 1 (not 0),
- * it is needed for Gauss' formula
- */
-
- if (--month <= 0) {
- month += 12;
- year -= 1;
- }
-
- /* Gauss' formula for Gregorian days since March 1, 1 BC */
-
- time = (guint64) (
- /* days in years including leap years since March 1, 1 BC */
-
- 365 * year + year / 4 - year / 100 + year / 400
-
- /* days before the month */
-
- + 367 * month / 12 - 30
-
- /* days before the day */
-
- + day - 1
-
- /*
- * 719527 days were between March 1, 1 BC and March 1, 1970,
- * 31 and 28 days were in January and February 1970
- */
-
- - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
-
- return (time_t) time;
-}
-
static void
rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn,
struct rspamd_http_connection_private *priv)
@@ -430,9 +165,10 @@ rspamd_http_parse_key (rspamd_ftok_t *data, struct rspamd_http_connection *conn,
RSPAMD_KEYPAIR_SHORT_ID_LEN) == 0) {
priv->msg->peer_key = pk;
- if (conn->cache && priv->msg->peer_key) {
- rspamd_keypair_cache_process (conn->cache,
- priv->local_key, priv->msg->peer_key);
+ if (priv->cache && priv->msg->peer_key) {
+ rspamd_keypair_cache_process (priv->cache,
+ priv->local_key,
+ priv->msg->peer_key);
}
}
else {
@@ -1299,13 +1035,12 @@ rspamd_http_parser_reset (struct rspamd_http_connection *conn)
struct rspamd_http_connection *
rspamd_http_connection_new (
+ struct rspamd_http_context *ctx,
rspamd_http_body_handler_t body_handler,
rspamd_http_error_handler_t error_handler,
rspamd_http_finish_handler_t finish_handler,
unsigned opts,
- enum rspamd_http_connection_type type,
- struct rspamd_keypair_cache *cache,
- gpointer ssl_ctx)
+ enum rspamd_http_connection_type type)
{
struct rspamd_http_connection *conn;
struct rspamd_http_connection_private *priv;
@@ -1323,12 +1058,25 @@ rspamd_http_connection_new (
conn->fd = -1;
conn->ref = 1;
conn->finished = FALSE;
- conn->cache = cache;
/* Init priv */
+ if (ctx == NULL) {
+ ctx = rspamd_http_context_default ();
+ }
+
priv = g_malloc0 (sizeof (struct rspamd_http_connection_private));
conn->priv = priv;
- priv->ssl_ctx = ssl_ctx;
+ priv->ctx = ctx;
+
+ if (conn->type == RSPAMD_HTTP_CLIENT) {
+ priv->cache = ctx->client_kp_cache;
+ if (ctx->client_kp) {
+ priv->local_key = rspamd_keypair_ref (ctx->client_kp);
+ }
+ }
+ else {
+ priv->cache = ctx->server_kp_cache;
+ }
rspamd_http_parser_reset (conn);
priv->parser.data = conn;
@@ -2022,8 +1770,8 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
encrypted = TRUE;
- if (conn->cache) {
- rspamd_keypair_cache_process (conn->cache,
+ if (priv->cache) {
+ rspamd_keypair_cache_process (priv->cache,
priv->local_key, priv->msg->peer_key);
}
}
@@ -2287,10 +2035,14 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
}
if (msg->flags & RSPAMD_HTTP_FLAG_SSL) {
+ gpointer ssl_ctx = (msg->flags & RSPAMD_HTTP_FLAG_SSL_NOVERIFY) ?
+ priv->ctx->ssl_ctx_noverify : priv->ctx->ssl_ctx;
+
if (base != NULL) {
event_base_set (base, &priv->ev);
}
- if (!priv->ssl_ctx) {
+
+ if (!ssl_ctx) {
err = g_error_new (HTTP_ERROR, errno, "ssl message requested "
"with no ssl ctx");
rspamd_http_connection_ref (conn);
@@ -2305,7 +2057,7 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
rspamd_ssl_connection_free (priv->ssl);
}
- priv->ssl = rspamd_ssl_connection_new (priv->ssl_ctx, base,
+ priv->ssl = rspamd_ssl_connection_new (ssl_ctx, base,
!(msg->flags & RSPAMD_HTTP_FLAG_SSL_NOVERIFY));
g_assert (priv->ssl != NULL);
diff --git a/src/libutil/http_connection.h b/src/libutil/http_connection.h
index 1fa1170b2..4e9f9f800 100644
--- a/src/libutil/http_connection.h
+++ b/src/libutil/http_connection.h
@@ -24,8 +24,7 @@
*/
#include "config.h"
-#include "keypair.h"
-#include "keypairs_cache.h"
+#include "http_context.h"
#include "fstring.h"
#include "ref.h"
#include "http_message.h"
@@ -104,7 +103,6 @@ struct rspamd_http_connection {
rspamd_http_body_handler_t body_handler;
rspamd_http_error_handler_t error_handler;
rspamd_http_finish_handler_t finish_handler;
- struct rspamd_keypair_cache *cache;
gpointer ud;
gsize max_size;
unsigned opts;
@@ -121,13 +119,12 @@ struct rspamd_http_connection {
* @return new connection structure
*/
struct rspamd_http_connection *rspamd_http_connection_new (
+ struct rspamd_http_context *ctx,
rspamd_http_body_handler_t body_handler,
rspamd_http_error_handler_t error_handler,
rspamd_http_finish_handler_t finish_handler,
unsigned opts,
- enum rspamd_http_connection_type type,
- struct rspamd_keypair_cache *cache,
- gpointer ssl_ctx);
+ enum rspamd_http_connection_type type);
/**
diff --git a/src/libutil/http_private.h b/src/libutil/http_private.h
index df1233d8b..0f8c847a2 100644
--- a/src/libutil/http_private.h
+++ b/src/libutil/http_private.h
@@ -19,6 +19,8 @@
#include "http_connection.h"
#include "http_parser.h"
#include "str_util.h"
+#include "keypair.h"
+#include "keypairs_cache.h"
#include "ref.h"
#define HASH_CASELESS
#include "uthash_strcase.h"
@@ -74,6 +76,17 @@ struct rspamd_http_message {
ref_entry_t ref;
};
+struct rspamd_http_context {
+ struct rspamd_http_context_cfg config;
+ struct rspamd_keypair_cache *client_kp_cache;
+ struct rspamd_cryptobox_keypair *client_kp;
+ struct rspamd_keypair_cache *server_kp_cache;
+ gpointer ssl_ctx;
+ gpointer ssl_ctx_noverify;
+ struct event_base *ev_base;
+ struct event client_rotate_ev;
+};
+
#define HTTP_ERROR http_error_quark ()
GQuark http_error_quark (void);
diff --git a/src/libutil/http_router.c b/src/libutil/http_router.c
index 0dc597788..be45c4351 100644
--- a/src/libutil/http_router.c
+++ b/src/libutil/http_router.c
@@ -373,9 +373,9 @@ rspamd_http_router_finish_handler (struct rspamd_http_connection *conn,
struct rspamd_http_connection_router *
rspamd_http_router_new (rspamd_http_router_error_handler_t eh,
rspamd_http_router_finish_handler_t fh,
- struct timeval *timeout, struct event_base *base,
+ struct timeval *timeout,
const char *default_fs_path,
- struct rspamd_keypair_cache *cache)
+ struct rspamd_http_context *ctx)
{
struct rspamd_http_connection_router * new;
struct stat st;
@@ -387,7 +387,6 @@ rspamd_http_router_new (rspamd_http_router_error_handler_t eh,
new->conns = NULL;
new->error_handler = eh;
new->finish_handler = fh;
- new->ev_base = base;
new->response_headers = g_hash_table_new_full (rspamd_strcase_hash,
rspamd_strcase_equal, g_free, g_free);
@@ -415,7 +414,7 @@ rspamd_http_router_new (rspamd_http_router_error_handler_t eh,
}
}
- new->cache = cache;
+ new->ctx = ctx;
return new;
}
@@ -510,13 +509,12 @@ rspamd_http_router_handle_socket (struct rspamd_http_connection_router *router,
conn->ud = ud;
conn->is_reply = FALSE;
- conn->conn = rspamd_http_connection_new (NULL,
+ conn->conn = rspamd_http_connection_new (router->ctx,
+ NULL,
rspamd_http_router_error_handler,
rspamd_http_router_finish_handler,
0,
- RSPAMD_HTTP_SERVER,
- router->cache,
- NULL);
+ RSPAMD_HTTP_SERVER);
if (router->key) {
rspamd_http_connection_set_key (conn->conn, router->key);
@@ -543,10 +541,6 @@ rspamd_http_router_free (struct rspamd_http_connection_router *router)
rspamd_keypair_unref (router->key);
}
- if (router->cache) {
- rspamd_keypair_cache_destroy (router->cache);
- }
-
if (router->default_fs_path != NULL) {
g_free (router->default_fs_path);
}
diff --git a/src/libutil/http_router.h b/src/libutil/http_router.h
index 7440c519e..8e8056240 100644
--- a/src/libutil/http_router.h
+++ b/src/libutil/http_router.h
@@ -47,7 +47,7 @@ struct rspamd_http_connection_router {
struct timeval tv;
struct timeval *ptv;
struct event_base *ev_base;
- struct rspamd_keypair_cache *cache;
+ struct rspamd_http_context *ctx;
gchar *default_fs_path;
rspamd_http_router_handler_t unknown_method_handler;
struct rspamd_cryptobox_keypair *key;
@@ -67,9 +67,8 @@ struct rspamd_http_connection_router * rspamd_http_router_new (
rspamd_http_router_error_handler_t eh,
rspamd_http_router_finish_handler_t fh,
struct timeval *timeout,
- struct event_base *base,
const char *default_fs_path,
- struct rspamd_keypair_cache *cache);
+ struct rspamd_http_context *ctx);
/**
* Set encryption key for the HTTP router
diff --git a/src/libutil/http_util.c b/src/libutil/http_util.c
index 8e220adfa..8fb658e08 100644
--- a/src/libutil/http_util.c
+++ b/src/libutil/http_util.c
@@ -22,6 +22,272 @@ static const gchar *http_week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "S
static const gchar *http_month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+/*
+ * Obtained from nginx
+ * Copyright (C) Igor Sysoev
+ */
+static guint mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+time_t
+rspamd_http_parse_date (const gchar *header, gsize len)
+{
+ const gchar *p, *end;
+ gint month;
+ guint day, year, hour, min, sec;
+ guint64 time;
+ enum {
+ no = 0, rfc822, /* Tue, 10 Nov 2002 23:50:13 */
+ rfc850, /* Tuesday, 10-Dec-02 23:50:13 */
+ isoc /* Tue Dec 10 23:50:13 2002 */
+ } fmt;
+
+ fmt = 0;
+ if (len > 0) {
+ end = header + len;
+ }
+ else {
+ end = header + strlen (header);
+ }
+
+ day = 32;
+ year = 2038;
+
+ for (p = header; p < end; p++) {
+ if (*p == ',') {
+ break;
+ }
+
+ if (*p == ' ') {
+ fmt = isoc;
+ break;
+ }
+ }
+
+ for (p++; p < end; p++)
+ if (*p != ' ') {
+ break;
+ }
+
+ if (end - p < 18) {
+ return (time_t)-1;
+ }
+
+ if (fmt != isoc) {
+ if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
+ return (time_t)-1;
+ }
+
+ day = (*p - '0') * 10 + *(p + 1) - '0';
+ p += 2;
+
+ if (*p == ' ') {
+ if (end - p < 18) {
+ return (time_t)-1;
+ }
+ fmt = rfc822;
+
+ }
+ else if (*p == '-') {
+ fmt = rfc850;
+
+ }
+ else {
+ return (time_t)-1;
+ }
+
+ p++;
+ }
+
+ switch (*p) {
+
+ case 'J':
+ month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
+ break;
+
+ case 'F':
+ month = 1;
+ break;
+
+ case 'M':
+ month = *(p + 2) == 'r' ? 2 : 4;
+ break;
+
+ case 'A':
+ month = *(p + 1) == 'p' ? 3 : 7;
+ break;
+
+ case 'S':
+ month = 8;
+ break;
+
+ case 'O':
+ month = 9;
+ break;
+
*** OUTPUT TRUNCATED, 405 LINES SKIPPED ***
More information about the Commits
mailing list