commit f0dc58b: [Project] More rework for HTTP proxy support
Vsevolod Stakhov
vsevolod at highsecure.ru
Mon Mar 18 16:21:06 UTC 2019
Author: Vsevolod Stakhov
Date: 2019-03-18 15:32:54 +0000
URL: https://github.com/rspamd/rspamd/commit/f0dc58b678766902780598c9cdffed8188e070f5
[Project] More rework for HTTP proxy support
---
src/libutil/http_connection.c | 157 +++++++++++++++++++++++++++---------------
src/libutil/http_connection.h | 1 -
src/plugins/surbl.c | 6 +-
3 files changed, 104 insertions(+), 60 deletions(-)
diff --git a/src/libutil/http_connection.c b/src/libutil/http_connection.c
index d782c2d13..e75e26a45 100644
--- a/src/libutil/http_connection.c
+++ b/src/libutil/http_connection.c
@@ -51,6 +51,7 @@ enum rspamd_http_priv_flags {
RSPAMD_HTTP_CONN_FLAG_ENCRYPTION_NEEDED = 1 << 4,
RSPAMD_HTTP_CONN_FLAG_PROXY = 1 << 5,
RSPAMD_HTTP_CONN_FLAG_PROXY_REQUEST = 1 << 6,
+ RSPAMD_HTTP_CONN_OWN_SOCKET = 1 << 7,
};
#define IS_CONN_ENCRYPTED(c) ((c)->flags & RSPAMD_HTTP_CONN_FLAG_ENCRYPTED)
@@ -1078,24 +1079,25 @@ rspamd_http_parser_reset (struct rspamd_http_connection *conn)
priv->parser_cb.on_message_complete = rspamd_http_on_message_complete;
}
-struct rspamd_http_connection *
-rspamd_http_connection_new_server (struct rspamd_http_context *ctx,
+static struct rspamd_http_connection *
+rspamd_http_connection_new_common (struct rspamd_http_context *ctx,
gint fd,
rspamd_http_body_handler_t body_handler,
rspamd_http_error_handler_t error_handler,
rspamd_http_finish_handler_t finish_handler,
- unsigned opts)
+ unsigned opts,
+ enum rspamd_http_connection_type type,
+ enum rspamd_http_priv_flags priv_flags,
+ struct upstream *proxy_upstream)
{
struct rspamd_http_connection *conn;
struct rspamd_http_connection_private *priv;
- if (error_handler == NULL || finish_handler == NULL) {
- return NULL;
- }
+ g_assert (error_handler != NULL && finish_handler == NULL);
conn = g_malloc0 (sizeof (struct rspamd_http_connection));
conn->opts = opts;
- conn->type = RSPAMD_HTTP_SERVER;
+ conn->type = type;
conn->body_handler = body_handler;
conn->error_handler = error_handler;
conn->finish_handler = finish_handler;
@@ -1111,8 +1113,17 @@ rspamd_http_connection_new_server (struct rspamd_http_context *ctx,
priv = g_malloc0 (sizeof (struct rspamd_http_connection_private));
conn->priv = priv;
priv->ctx = ctx;
+ priv->flags = priv_flags;
- priv->cache = ctx->server_kp_cache;
+ if (type == RSPAMD_HTTP_SERVER) {
+ priv->cache = ctx->server_kp_cache;
+ }
+ else {
+ priv->cache = ctx->client_kp_cache;
+ if (ctx->client_kp) {
+ priv->local_key = rspamd_keypair_ref (ctx->client_kp);
+ }
+ }
rspamd_http_parser_reset (conn);
priv->parser.data = conn;
@@ -1120,6 +1131,18 @@ rspamd_http_connection_new_server (struct rspamd_http_context *ctx,
return conn;
}
+struct rspamd_http_connection *
+rspamd_http_connection_new_server (struct rspamd_http_context *ctx,
+ gint fd,
+ rspamd_http_body_handler_t body_handler,
+ rspamd_http_error_handler_t error_handler,
+ rspamd_http_finish_handler_t finish_handler,
+ unsigned opts)
+{
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts, RSPAMD_HTTP_SERVER, 0, NULL);
+}
+
struct rspamd_http_connection *
rspamd_http_connection_new_client_socket (struct rspamd_http_context *ctx,
rspamd_http_body_handler_t body_handler,
@@ -1128,39 +1151,8 @@ rspamd_http_connection_new_client_socket (struct rspamd_http_context *ctx,
unsigned opts,
gint fd)
{
- struct rspamd_http_connection *conn;
- struct rspamd_http_connection_private *priv;
-
- g_assert (error_handler != NULL && finish_handler == NULL);
-
- conn = g_malloc0 (sizeof (struct rspamd_http_connection));
- conn->opts = opts;
- conn->type = RSPAMD_HTTP_CLIENT;
- conn->body_handler = body_handler;
- conn->error_handler = error_handler;
- conn->finish_handler = finish_handler;
- conn->fd = fd;
- conn->ref = 1;
- conn->finished = FALSE;
-
- /* Init priv */
- if (ctx == NULL) {
- ctx = rspamd_http_context_default ();
- }
-
- priv = g_malloc0 (sizeof (struct rspamd_http_connection_private));
- conn->priv = priv;
- priv->ctx = ctx;
-
- priv->cache = ctx->client_kp_cache;
- if (ctx->client_kp) {
- priv->local_key = rspamd_keypair_ref (ctx->client_kp);
- }
-
- rspamd_http_parser_reset (conn);
- priv->parser.data = conn;
-
- return conn;
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts, RSPAMD_HTTP_CLIENT, 0, NULL);
}
struct rspamd_http_connection *
@@ -1173,21 +1165,77 @@ rspamd_http_connection_new_client (struct rspamd_http_context *ctx,
{
gint fd;
- if (error_handler == NULL || finish_handler == NULL) {
- return NULL;
+ if (opts & RSPAMD_HTTP_CLIENT_ENCRYPTED) {
+ if (ctx->https_proxies) {
+ struct upstream *up = rspamd_upstream_get (ctx->https_proxies,
+ RSPAMD_UPSTREAM_ROUND_ROBIN, NULL, 0);
+
+ if (up) {
+ rspamd_inet_addr_t *proxy_addr = rspamd_upstream_addr_next (up);
+
+ fd = rspamd_inet_address_connect (proxy_addr, SOCK_STREAM, TRUE);
+
+ if (fd == -1) {
+ msg_info ("cannot connect to https proxy %s: %s",
+ rspamd_inet_address_to_string (proxy_addr),
+ strerror (errno));
+ rspamd_upstream_fail (up, TRUE);
+
+ return NULL;
+ }
+
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts,
+ RSPAMD_HTTP_CLIENT,
+ RSPAMD_HTTP_CONN_OWN_SOCKET|RSPAMD_HTTP_CONN_FLAG_PROXY,
+ up);
+ }
+ }
+ }
+ else {
+ if (ctx->http_proxies) {
+ struct upstream *up = rspamd_upstream_get (ctx->http_proxies,
+ RSPAMD_UPSTREAM_ROUND_ROBIN, NULL, 0);
+
+ if (up) {
+ rspamd_inet_addr_t *proxy_addr = rspamd_upstream_addr_next (up);
+
+ fd = rspamd_inet_address_connect (proxy_addr, SOCK_STREAM, TRUE);
+
+ if (fd == -1) {
+ msg_info ("cannot connect to http proxy %s: %s",
+ rspamd_inet_address_to_string (proxy_addr),
+ strerror (errno));
+ rspamd_upstream_fail (up, TRUE);
+
+ return NULL;
+ }
+
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts,
+ RSPAMD_HTTP_CLIENT,
+ RSPAMD_HTTP_CONN_OWN_SOCKET|RSPAMD_HTTP_CONN_FLAG_PROXY,
+ up);
+ }
+ }
}
+ /* Unproxied version */
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),
+ msg_info ("cannot connect to proxy %s: %s",
+ rspamd_inet_address_to_string (addr),
strerror (errno));
+
return NULL;
}
- return rspamd_http_connection_new_client_socket (ctx,
- body_handler, error_handler, finish_handler,
- opts | RSPAMD_HTTP_OWN_SOCKET, fd);
+ return rspamd_http_connection_new_common (ctx, fd, body_handler,
+ error_handler, finish_handler, opts,
+ RSPAMD_HTTP_CLIENT,
+ RSPAMD_HTTP_CONN_OWN_SOCKET,
+ NULL);
}
struct rspamd_http_connection *
@@ -1200,10 +1248,6 @@ rspamd_http_connection_new_keepalive (struct rspamd_http_context *ctx,
{
struct rspamd_http_connection *conn;
- if (error_handler == NULL || finish_handler == NULL) {
- return NULL;
- }
-
if (ctx == NULL) {
ctx = rspamd_http_context_default ();
}
@@ -1437,12 +1481,12 @@ rspamd_http_connection_free (struct rspamd_http_connection *conn)
rspamd_pubkey_unref (priv->peer_key);
}
- g_free (priv);
- }
+ if (priv->flags & RSPAMD_HTTP_CONN_OWN_SOCKET) {
+ /* Fd is owned by a connection */
+ close (conn->fd);
+ }
- if (conn->opts & RSPAMD_HTTP_OWN_SOCKET) {
- /* Fd is owned by a connection */
- close (conn->fd);
+ g_free (priv);
}
g_free (conn);
@@ -1810,6 +1854,7 @@ rspamd_http_message_write_header (const gchar* mime_type, gboolean encrypted,
}
}
else {
+ /* Normal HTTP/1.1 with Host */
if (encrypted) {
if (host != NULL) {
rspamd_printf_fstring (buf,
diff --git a/src/libutil/http_connection.h b/src/libutil/http_connection.h
index da354ac41..6240772da 100644
--- a/src/libutil/http_connection.h
+++ b/src/libutil/http_connection.h
@@ -85,7 +85,6 @@ enum rspamd_http_options {
RSPAMD_HTTP_CLIENT_SHARED = 1u << 3, /**< Store reply in shared memory */
RSPAMD_HTTP_REQUIRE_ENCRYPTION = 1u << 4,
RSPAMD_HTTP_CLIENT_KEEP_ALIVE = 1u << 5,
- RSPAMD_HTTP_OWN_SOCKET = 1u << 6,
};
typedef int (*rspamd_http_body_handler_t) (struct rspamd_http_connection *conn,
diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c
index 3f1990b7b..11d3e35d9 100644
--- a/src/plugins/surbl.c
+++ b/src/plugins/surbl.c
@@ -1788,6 +1788,8 @@ register_redirector_call (struct rspamd_url *url, struct rspamd_task *task,
selected = rspamd_upstream_get (surbl_module_ctx->redirectors,
RSPAMD_UPSTREAM_ROUND_ROBIN, url->host, url->hostlen);
+ param = rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct redirector_param));
if (selected) {
param->conn = rspamd_http_connection_new_client (NULL,
@@ -1806,9 +1808,7 @@ register_redirector_call (struct rspamd_url *url, struct rspamd_task *task,
return;
}
- param =
- rspamd_mempool_alloc (task->task_pool,
- sizeof (struct redirector_param));
+
param->url = url;
param->task = task;
param->ctx = surbl_module_ctx;
More information about the Commits
mailing list