aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2019-03-05 12:43:07 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2019-03-05 12:43:07 +0000
commitff5125a975f3a3c143c84aa9cf2f6878f5930272 (patch)
treeee759abdc966c3415a87ea4ad91c8f10f2c132f7
parentf0462bf947bafb429f47162a84b4daaf7379463e (diff)
downloadrspamd-ff5125a975f3a3c143c84aa9cf2f6878f5930272.tar.gz
rspamd-ff5125a975f3a3c143c84aa9cf2f6878f5930272.zip
[Project] Plug keepalive knobs into http connection handling
-rw-r--r--src/libutil/http_connection.c76
-rw-r--r--src/libutil/http_context.c1
2 files changed, 74 insertions, 3 deletions
diff --git a/src/libutil/http_connection.c b/src/libutil/http_connection.c
index d59782997..9e43e21e2 100644
--- a/src/libutil/http_connection.c
+++ b/src/libutil/http_connection.c
@@ -352,7 +352,15 @@ rspamd_http_on_headers_complete (http_parser * parser)
msg->code = parser->status_code;
rspamd_http_connection_ref (conn);
ret = conn->finish_handler (conn, msg);
- conn->finished = TRUE;
+
+ if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
+ rspamd_http_context_push_keepalive (conn->priv->ctx, conn,
+ msg, conn->priv->ctx->ev_base);
+ }
+ else {
+ conn->finished = TRUE;
+ }
+
rspamd_http_connection_unref (conn);
return ret;
@@ -527,7 +535,15 @@ rspamd_http_on_headers_complete_decrypted (http_parser *parser)
msg->code = parser->status_code;
rspamd_http_connection_ref (conn);
ret = conn->finish_handler (conn, msg);
- conn->finished = TRUE;
+
+ if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
+ rspamd_http_context_push_keepalive (conn->priv->ctx, conn,
+ msg, conn->priv->ctx->ev_base);
+ }
+ else {
+ conn->finished = TRUE;
+ }
+
rspamd_http_connection_unref (conn);
return ret;
@@ -677,7 +693,15 @@ rspamd_http_on_message_complete (http_parser * parser)
rspamd_http_connection_ref (conn);
ret = conn->finish_handler (conn, priv->msg);
- conn->finished = TRUE;
+
+ if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
+ rspamd_http_context_push_keepalive (conn->priv->ctx, conn,
+ priv->msg, conn->priv->ctx->ev_base);
+ }
+ else {
+ conn->finished = TRUE;
+ }
+
rspamd_http_connection_unref (conn);
}
@@ -1096,6 +1120,47 @@ rspamd_http_connection_new (
return conn;
}
+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)
+{
+ struct rspamd_http_connection *conn;
+ gint fd;
+
+ if (error_handler == NULL || finish_handler == NULL) {
+ return NULL;
+ }
+
+ conn = rspamd_http_context_check_keepalive (ctx, addr, host);
+
+ if (conn) {
+ return conn;
+ }
+
+ fd = rspamd_inet_address_connect (addr, SOCK_STREAM, TRUE);
+
+ if (fd == -1) {
+ msg_info ("cannot connect to %s: %s", rspamd_inet_address_to_string (addr),
+ host);
+ return NULL;
+ }
+
+ conn = rspamd_http_connection_new (ctx, fd, body_handler, error_handler,
+ finish_handler,
+ RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_KEEP_ALIVE,
+ RSPAMD_HTTP_CLIENT);
+
+ if (conn) {
+ rspamd_http_context_prepare_keepalive (ctx, conn, addr, host);
+ }
+
+ return conn;
+}
+
void
rspamd_http_connection_reset (struct rspamd_http_connection *conn)
{
@@ -1310,6 +1375,11 @@ rspamd_http_connection_free (struct rspamd_http_connection *conn)
g_free (priv);
}
+ if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
+ /* Fd is owned by a connection */
+ close (conn->fd);
+ }
+
g_free (conn);
}
diff --git a/src/libutil/http_context.c b/src/libutil/http_context.c
index e326a74a1..da2481640 100644
--- a/src/libutil/http_context.c
+++ b/src/libutil/http_context.c
@@ -388,6 +388,7 @@ rspamd_http_context_push_keepalive (struct rspamd_http_context *ctx,
g_queue_push_tail (&conn->keepalive_hash_key->conns, cbdata);
cbdata->link = conn->keepalive_hash_key->conns.tail;
cbdata->queue = &conn->keepalive_hash_key->conns;
+ conn->finished = FALSE;
event_set (&cbdata->ev, conn->fd, EV_READ|EV_TIMEOUT,
rspamd_http_keepalive_handler,