diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-03-04 14:15:05 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2019-03-04 14:15:05 +0000 |
commit | bcf9f0c5710a010783edef75742beef1192c89fb (patch) | |
tree | 39e072cb79716689b5e96aadf32eaea24d2b815e /src | |
parent | 22f053689ae2c3bf6ca5f6b27410ac4413c4e7f8 (diff) | |
download | rspamd-bcf9f0c5710a010783edef75742beef1192c89fb.tar.gz rspamd-bcf9f0c5710a010783edef75742beef1192c89fb.zip |
[Project] Start keep alive connections cache implementation
Diffstat (limited to 'src')
-rw-r--r-- | src/libutil/http_connection.c | 48 | ||||
-rw-r--r-- | src/libutil/http_connection.h | 13 | ||||
-rw-r--r-- | src/libutil/http_context.c | 31 | ||||
-rw-r--r-- | src/libutil/http_private.h | 14 |
4 files changed, 91 insertions, 15 deletions
diff --git a/src/libutil/http_connection.c b/src/libutil/http_connection.c index b1df4e335..7bc92cb1f 100644 --- a/src/libutil/http_connection.c +++ b/src/libutil/http_connection.c @@ -1489,6 +1489,7 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted, { gchar datebuf[64]; gint meth_len = 0; + const gchar *conn_type = "close"; if (conn->type == RSPAMD_HTTP_SERVER) { /* Format reply */ @@ -1619,6 +1620,10 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted, } } else { + if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) { + conn_type = "keep-alive"; + } + /* Format request */ enclen += msg->url->len + strlen (http_method_str (msg->method)) + 1; @@ -1629,14 +1634,20 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted, "%s %s HTTP/1.0\r\n" "Content-Length: %z\r\n" "Content-Type: application/octet-stream\r\n", + "Connection: %s\r\n", "POST", - "/post", enclen); + "/post", + enclen, + conn_type); } else { rspamd_printf_fstring (buf, "%s %V HTTP/1.0\r\n" - "Content-Length: %z\r\n", - http_method_str (msg->method), msg->url, bodylen); + "Content-Length: %z\r\n" + "Connection: %s\r\n", + http_method_str (msg->method), msg->url, bodylen, + conn_type); + if (bodylen > 0) { if (mime_type == NULL) { mime_type = "text/plain"; @@ -1653,38 +1664,53 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted, if (host != NULL) { rspamd_printf_fstring (buf, "%s %s HTTP/1.1\r\n" - "Connection: close\r\n" + "Connection: %s\r\n" "Host: %s\r\n" "Content-Length: %z\r\n" "Content-Type: application/octet-stream\r\n", - "POST", "/post", host, enclen); + "POST", + "/post", + conn_type, + host, + enclen); } else { rspamd_printf_fstring (buf, "%s %s HTTP/1.1\r\n" - "Connection: close\r\n" + "Connection: %s\r\n" "Host: %V\r\n" "Content-Length: %z\r\n" "Content-Type: application/octet-stream\r\n", - "POST", "/post", msg->host, enclen); + "POST", + "/post", + conn_type, + msg->host, + enclen); } } else { if (host != NULL) { rspamd_printf_fstring (buf, - "%s %V HTTP/1.1\r\nConnection: close\r\n" + "%s %V HTTP/1.1\r\n" + "Connection: %s\r\n" "Host: %s\r\n" "Content-Length: %z\r\n", - http_method_str (msg->method), msg->url, host, + http_method_str (msg->method), + msg->url, + conn_type, + host, bodylen); } else { rspamd_printf_fstring (buf, "%s %V HTTP/1.1\r\n" - "Connection: close\r\n" + "Connection: %s\r\n" "Host: %V\r\n" "Content-Length: %z\r\n", - http_method_str (msg->method), msg->url, msg->host, + http_method_str (msg->method), + msg->url, + conn_type, + msg->host, bodylen); } diff --git a/src/libutil/http_connection.h b/src/libutil/http_connection.h index 5fadf4509..87159bdd0 100644 --- a/src/libutil/http_connection.h +++ b/src/libutil/http_connection.h @@ -29,6 +29,7 @@ #include "ref.h" #include "http_message.h" #include "http_util.h" +#include "addr.h" #include <event.h> @@ -74,10 +75,6 @@ struct rspamd_storage_shmem { */ #define RSPAMD_HTTP_FLAG_SSL_NOVERIFY (1 << 6) /** - * Do not verify server's certificate - */ -#define RSPAMD_HTTP_FLAG_KEEPALIVE (1 << 7) -/** * Options for HTTP connection */ enum rspamd_http_options { @@ -132,6 +129,14 @@ struct rspamd_http_connection *rspamd_http_connection_new ( unsigned opts, enum rspamd_http_connection_type type); +struct rspamd_http_connection *rspamd_http_connection_new_keepalive ( + 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, + rspamd_inet_addr_t *addr, + const gchar *host); + /** * Set key pointed by an opaque pointer diff --git a/src/libutil/http_context.c b/src/libutil/http_context.c index d5ab49450..6695e8032 100644 --- a/src/libutil/http_context.c +++ b/src/libutil/http_context.c @@ -207,4 +207,35 @@ rspamd_http_context_default (void) g_assert (default_ctx != NULL); return default_ctx; +} + +gint32 +rspamd_keep_alive_key_hash (struct rspamd_keepalive_hash_key k) +{ + gint32 h; + + h = rspamd_inet_address_port_hash (k.addr); + + if (k.host) { + h = rspamd_cryptobox_fast_hash (k.host, strlen (k.host), h); + } + + return h; +} + +bool +rspamd_keep_alive_key_equal (struct rspamd_keepalive_hash_key k1, + struct rspamd_keepalive_hash_key k2) +{ + if (k1.host && k2.host) { + if (rspamd_inet_address_port_equal (k1.addr, k2.addr)) { + return strcmp (k1.host, k2.host); + } + } + else if (!k1.host && !k2.host) { + return rspamd_inet_address_port_equal (k1.addr, k2.addr); + } + + /* One has host and another has no host */ + return false; }
\ No newline at end of file diff --git a/src/libutil/http_private.h b/src/libutil/http_private.h index 0f8c847a2..29c6ea45f 100644 --- a/src/libutil/http_private.h +++ b/src/libutil/http_private.h @@ -22,6 +22,7 @@ #include "keypair.h" #include "keypairs_cache.h" #include "ref.h" +#include "khash.h" #define HASH_CASELESS #include "uthash_strcase.h" @@ -76,6 +77,18 @@ struct rspamd_http_message { ref_entry_t ref; }; +struct rspamd_keepalive_hash_key { + rspamd_inet_addr_t *addr; + gchar *host; +}; + +gint32 rspamd_keep_alive_key_hash (struct rspamd_keepalive_hash_key k); +bool rspamd_keep_alive_key_equal (struct rspamd_keepalive_hash_key k1, + struct rspamd_keepalive_hash_key k2); + +KHASH_INIT (rspamd_keep_alive_hash, struct rspamd_keepalive_hash_key, + GQueue, true, rspamd_keep_alive_key_hash, rspamd_keep_alive_key_equal); + struct rspamd_http_context { struct rspamd_http_context_cfg config; struct rspamd_keypair_cache *client_kp_cache; @@ -85,6 +98,7 @@ struct rspamd_http_context { gpointer ssl_ctx_noverify; struct event_base *ev_base; struct event client_rotate_ev; + khash_t (rspamd_keep_alive_hash) *keep_alive_hash; }; #define HTTP_ERROR http_error_quark () |