conn->ev_base = ev_base;
conn->fd = fd;
conn->req_sent = FALSE;
- conn->http_conn = rspamd_http_connection_new (http_ctx,
- fd,
+ conn->http_conn = rspamd_http_connection_new_client_socket (http_ctx,
rspamd_client_body_handler,
rspamd_client_error_handler,
rspamd_client_finish_handler,
0,
- RSPAMD_HTTP_CLIENT);
+ fd);
conn->server_name = g_string_new (name);
if (port != 0) {
msg = rspamd_http_new_message (HTTP_REQUEST);
rspamd_printf_fstring (&msg->url, "/update_v1/%s", m->name);
- conn->http_conn = rspamd_http_connection_new (
+ conn->http_conn = rspamd_http_connection_new_client_socket (
ctx->http_ctx,
- conn->sock,
NULL,
fuzzy_mirror_error_handler,
fuzzy_mirror_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ conn->sock);
rspamd_http_connection_set_key (conn->http_conn,
ctx->sync_keypair);
session->name = rspamd_inet_address_to_string (addr);
rspamd_random_hex (session->uid, sizeof (session->uid) - 1);
session->uid[sizeof (session->uid) - 1] = '\0';
- http_conn = rspamd_http_connection_new (
+ http_conn = rspamd_http_connection_new_server (
ctx->http_ctx,
nfd,
NULL,
rspamd_fuzzy_mirror_error_handler,
rspamd_fuzzy_mirror_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
rspamd_http_connection_set_key (http_conn, ctx->sync_keypair);
session->ctx = ctx;
session = g_malloc0 (sizeof (*session));
session->fd = fd;
- session->conn = rspamd_http_connection_new (rspamd_main->http_ctx,
+ session->conn = rspamd_http_connection_new_server (rspamd_main->http_ctx,
fd,
NULL,
rspamd_control_error_handler,
rspamd_control_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
session->rspamd_main = rspamd_main;
session->addr = addr;
rspamd_http_connection_read_message (session->conn, session,
}
struct rspamd_http_connection *
-rspamd_http_connection_new (
- 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,
- enum rspamd_http_connection_type type)
+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)
{
struct rspamd_http_connection *conn;
struct rspamd_http_connection_private *priv;
conn = g_malloc0 (sizeof (struct rspamd_http_connection));
conn->opts = opts;
- conn->type = type;
+ conn->type = RSPAMD_HTTP_SERVER;
conn->body_handler = body_handler;
conn->error_handler = error_handler;
conn->finish_handler = finish_handler;
conn->priv = priv;
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);
- }
+ priv->cache = ctx->server_kp_cache;
+
+ rspamd_http_parser_reset (conn);
+ priv->parser.data = conn;
+
+ return conn;
+}
+
+struct rspamd_http_connection *
+rspamd_http_connection_new_client_socket (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,
+ 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 ();
}
- else {
- priv->cache = ctx->server_kp_cache;
+
+ 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);
return conn;
}
+struct rspamd_http_connection *
+rspamd_http_connection_new_client (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,
+ rspamd_inet_addr_t *addr)
+{
+ gint fd;
+
+ if (error_handler == NULL || finish_handler == NULL) {
+ return NULL;
+ }
+
+ 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),
+ strerror (errno));
+ return NULL;
+ }
+
+ return rspamd_http_connection_new_client_socket (ctx,
+ body_handler, error_handler, finish_handler,
+ opts | RSPAMD_HTTP_OWN_SOCKET, fd);
+}
+
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)
+ 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;
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,
+ conn = rspamd_http_connection_new_client (ctx,
+ body_handler, error_handler, finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_KEEP_ALIVE,
- RSPAMD_HTTP_CLIENT);
+ addr);
if (conn) {
rspamd_http_context_prepare_keepalive (ctx, conn, addr, host);
g_free (priv);
}
- if (conn->opts & RSPAMD_HTTP_CLIENT_KEEP_ALIVE) {
+ if (conn->opts & RSPAMD_HTTP_OWN_SOCKET) {
/* Fd is owned by a connection */
close (conn->fd);
}
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,
};
/**
- * Create new http connection
- * @param handler_t handler_t for body
- * @param opts options
- * @return new connection structure
+ * Creates a new HTTP server connection from an opened FD returned by accept function
+ * @param ctx
+ * @param fd
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param opts
+ * @return
*/
-struct rspamd_http_connection *rspamd_http_connection_new (
+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,
- enum rspamd_http_connection_type type);
+ unsigned opts);
+/**
+ * Creates or reuses a new keepalive client connection identified by hostname and inet_addr
+ * @param ctx
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param addr
+ * @param host
+ * @return
+ */
struct rspamd_http_connection *rspamd_http_connection_new_keepalive (
struct rspamd_http_context *ctx,
rspamd_http_body_handler_t body_handler,
rspamd_inet_addr_t *addr,
const gchar *host);
+/**
+ * Creates an ordinary connection using the address specified (if proxy is not set)
+ * @param ctx
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param opts
+ * @param addr
+ * @return
+ */
+struct rspamd_http_connection *rspamd_http_connection_new_client (
+ 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,
+ rspamd_inet_addr_t *addr);
+
+/**
+ * Creates an ordinary client connection using ready file descriptor (ignores proxy)
+ * @param ctx
+ * @param body_handler
+ * @param error_handler
+ * @param finish_handler
+ * @param opts
+ * @param addr
+ * @return
+ */
+struct rspamd_http_connection *rspamd_http_connection_new_client_socket (
+ 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,
+ gint fd);
/**
* Set key pointed by an opaque pointer
conn->ud = ud;
conn->is_reply = FALSE;
- conn->conn = rspamd_http_connection_new (router->ctx,
+ conn->conn = rspamd_http_connection_new_server (router->ctx,
fd,
NULL,
rspamd_http_router_error_handler,
rspamd_http_router_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
if (router->key) {
rspamd_http_connection_set_key (conn->conn, router->key);
struct rspamd_map *map;
map = cbd->map;
+ msg = rspamd_http_new_message (HTTP_REQUEST);
- if (cbd->fd != -1) {
- close (cbd->fd);
+ if (cbd->bk->protocol == MAP_PROTO_HTTPS) {
+ msg->flags |= RSPAMD_HTTP_FLAG_SSL;
}
- cbd->fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM, TRUE);
-
- if (cbd->fd != -1) {
- msg = rspamd_http_new_message (HTTP_REQUEST);
-
- if (cbd->bk->protocol == MAP_PROTO_HTTPS) {
- msg->flags |= RSPAMD_HTTP_FLAG_SSL;
- }
+ if (cbd->check) {
+ msg->method = HTTP_HEAD;
+ }
- if (cbd->check) {
- msg->method = HTTP_HEAD;
- }
+ if (cbd->stage == map_load_file) {
+ msg->url = rspamd_fstring_append (msg->url,
+ cbd->data->path, strlen (cbd->data->path));
- if (cbd->stage == map_load_file) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
-
- if (cbd->check && cbd->stage == map_load_file) {
- if (cbd->data->last_modified != 0) {
- rspamd_http_date_format (datebuf, sizeof (datebuf),
- cbd->data->last_modified);
- rspamd_http_message_add_header (msg, "If-Modified-Since",
- datebuf);
- }
- if (cbd->data->etag) {
- rspamd_http_message_add_header_len (msg, "If-None-Match",
- cbd->data->etag->str, cbd->data->etag->len);
- }
+ if (cbd->check && cbd->stage == map_load_file) {
+ if (cbd->data->last_modified != 0) {
+ rspamd_http_date_format (datebuf, sizeof (datebuf),
+ cbd->data->last_modified);
+ rspamd_http_message_add_header (msg, "If-Modified-Since",
+ datebuf);
+ }
+ if (cbd->data->etag) {
+ rspamd_http_message_add_header_len (msg, "If-None-Match",
+ cbd->data->etag->str, cbd->data->etag->len);
}
}
- else if (cbd->stage == map_load_pubkey) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
- msg->url = rspamd_fstring_append (msg->url, ".pub", 4);
- }
- else if (cbd->stage == map_load_signature) {
- msg->url = rspamd_fstring_append (msg->url,
- cbd->data->path, strlen (cbd->data->path));
- msg->url = rspamd_fstring_append (msg->url, ".sig", 4);
- }
- else {
- g_assert_not_reached ();
- }
-
- msg->url = rspamd_fstring_append (msg->url, cbd->data->rest,
- strlen (cbd->data->rest));
-
- if (cbd->data->userinfo) {
- rspamd_http_message_add_header (msg, "Authorization",
- cbd->data->userinfo);
- }
-
- MAP_RETAIN (cbd, "http_callback_data");
- rspamd_http_connection_write_message (cbd->conn,
- msg,
- cbd->data->host,
- NULL,
- cbd,
- &cbd->tv);
+ }
+ else if (cbd->stage == map_load_pubkey) {
+ msg->url = rspamd_fstring_append (msg->url,
+ cbd->data->path, strlen (cbd->data->path));
+ msg->url = rspamd_fstring_append (msg->url, ".pub", 4);
+ }
+ else if (cbd->stage == map_load_signature) {
+ msg->url = rspamd_fstring_append (msg->url,
+ cbd->data->path, strlen (cbd->data->path));
+ msg->url = rspamd_fstring_append (msg->url, ".sig", 4);
}
else {
- msg_err_map ("cannot connect to %s: %s", cbd->data->host,
- strerror (errno));
- cbd->periodic->errored = TRUE;
+ g_assert_not_reached ();
}
+
+ msg->url = rspamd_fstring_append (msg->url, cbd->data->rest,
+ strlen (cbd->data->rest));
+
+ if (cbd->data->userinfo) {
+ rspamd_http_message_add_header (msg, "Authorization",
+ cbd->data->userinfo);
+ }
+
+ MAP_RETAIN (cbd, "http_callback_data");
+ rspamd_http_connection_write_message (cbd->conn,
+ msg,
+ cbd->data->host,
+ NULL,
+ cbd,
+ &cbd->tv);
}
static gboolean
cbd->conn = NULL;
}
- if (cbd->fd != -1) {
- close (cbd->fd);
- }
-
if (cbd->addr) {
rspamd_inet_address_free (cbd->addr);
}
}
}
- rspamd_http_connection_reset (cbd->conn);
+ rspamd_http_connection_unref (cbd->conn);
+ cbd->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_SHARED,
+ cbd->addr);
write_http_request (cbd);
MAP_RELEASE (cbd, "http_callback_data");
}
cbd->stage = map_load_signature;
- rspamd_http_connection_reset (cbd->conn);
+ rspamd_http_connection_unref (cbd->conn);
+ cbd->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ RSPAMD_HTTP_CLIENT_SIMPLE|RSPAMD_HTTP_CLIENT_SHARED,
+ cbd->addr);
write_http_request (cbd);
MAP_RELEASE (cbd, "http_callback_data");
if (cbd->addr != NULL) {
rspamd_inet_address_set_port (cbd->addr, cbd->data->port);
- /* Try to open a socket */
- cbd->fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM,
- TRUE);
-
- if (cbd->fd != -1) {
+ cbd->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ flags,
+ cbd->addr);
+
+ if (cbd->conn != NULL) {
cbd->stage = map_load_file;
- cbd->conn = rspamd_http_connection_new (NULL,
- cbd->fd,
- NULL,
- http_map_error,
- http_map_finish,
- flags,
- RSPAMD_HTTP_CLIENT);
-
write_http_request (cbd);
}
else {
cbd->ev_base = map->ev_base;
cbd->map = map;
cbd->data = data;
- cbd->fd = -1;
cbd->check = check;
cbd->periodic = periodic;
MAP_RETAIN (periodic, "periodic");
/* Send both A and AAAA requests */
if (rspamd_parse_inet_address (&cbd->addr, data->host, strlen (data->host))) {
rspamd_inet_address_set_port (cbd->addr, cbd->data->port);
- cbd->fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM,
- TRUE);
+ cbd->conn = rspamd_http_connection_new_client (
+ NULL,
+ NULL,
+ http_map_error,
+ http_map_finish,
+ flags,
+ cbd->addr);
- if (cbd->fd != -1) {
+ if (cbd->conn != NULL) {
cbd->stage = map_load_file;
- cbd->conn = rspamd_http_connection_new (
- NULL,
- cbd->fd,
- NULL,
- http_map_error,
- http_map_finish,
- flags,
- RSPAMD_HTTP_CLIENT);
-
write_http_request (cbd);
MAP_RELEASE (cbd, "http_callback_data");
}
gsize pubkey_len;
enum rspamd_map_http_stage stage;
- gint fd;
struct timeval tv;
ref_entry_t ref;
static gboolean
lua_http_make_connection (struct lua_http_cbdata *cbd)
{
- int fd;
-
rspamd_inet_address_set_port (cbd->addr, cbd->msg->port);
if (cbd->flags & RSPAMD_LUA_HTTP_FLAG_KEEP_ALIVE) {
cbd->host);
}
else {
- fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM, TRUE);
-
- if (fd == -1) {
- msg_info ("cannot connect to %V", cbd->msg->host);
- return FALSE;
- }
-
- cbd->fd = fd;
- cbd->conn = rspamd_http_connection_new (
+ cbd->fd = -1;
+ cbd->conn = rspamd_http_connection_new_client (
NULL, /* Default context */
- fd,
NULL,
lua_http_error_handler,
lua_http_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ cbd->addr);
}
if (cbd->conn) {
GHashTable *tree;
struct suffix_item *suffix;
struct rspamd_symcache_item *item;
- gint sock;
guint redirector_requests;
};
}
rspamd_http_connection_unref (param->conn);
- close (param->sock);
}
static void
register_redirector_call (struct rspamd_url *url, struct rspamd_task *task,
const gchar *rule)
{
- gint s = -1;
struct redirector_param *param;
struct timeval *timeout;
struct upstream *selected;
RSPAMD_UPSTREAM_ROUND_ROBIN, url->host, url->hostlen);
if (selected) {
- s = rspamd_inet_address_connect (rspamd_upstream_addr_next (selected),
- SOCK_STREAM, TRUE);
+ param->conn = rspamd_http_connection_new_client (NULL,
+ NULL,
+ surbl_redirector_error,
+ surbl_redirector_finish,
+ RSPAMD_HTTP_CLIENT_SIMPLE,
+ rspamd_upstream_addr_next (selected));
}
- if (s == -1) {
+ if (param->conn == NULL) {
msg_info_surbl ("<%s> cannot create tcp socket failed: %s",
task->message_id,
strerror (errno));
sizeof (struct redirector_param));
param->url = url;
param->task = task;
- param->conn = rspamd_http_connection_new (NULL,
- s,
- NULL,
- surbl_redirector_error,
- surbl_redirector_finish,
- RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
param->ctx = surbl_module_ctx;
msg = rspamd_http_new_message (HTTP_REQUEST);
msg->url = rspamd_fstring_assign (msg->url, url->string, url->urllen);
- param->sock = s;
param->redirector = selected;
timeout = rspamd_mempool_alloc (task->task_pool, sizeof (struct timeval));
double_to_tv (surbl_module_ctx->read_timeout, timeout);
rspamd_inet_addr_t *addr;
struct timeval tv;
static struct rspamadm_control_cbdata cbdata;
- gint sock;
context = g_option_context_new (
"control - manage rspamd main control interface");
exit (1);
}
- sock = rspamd_inet_address_connect (addr, SOCK_STREAM, TRUE);
- if (sock == -1) {
- rspamd_fprintf (stderr, "cannot connect to: %s\n", control_path);
- rspamd_inet_address_free (addr);
- exit (1);
- }
-
- conn = rspamd_http_connection_new (
+ conn = rspamd_http_connection_new_client (
rspamd_main->http_ctx, /* Default context */
- sock,
NULL,
rspamd_control_error_handler,
rspamd_control_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ addr);
msg = rspamd_http_new_message (HTTP_REQUEST);
msg->url = rspamd_fstring_new_init (path, strlen (path));
double_to_tv (timeout, &tv);
rspamd_http_connection_unref (conn);
rspamd_inet_address_free (addr);
- close (sock);
}
rspamd_http_message_add_header (msg, "Settings-ID", m->settings_id);
}
- bk_conn->backend_conn = rspamd_http_connection_new (
+ bk_conn->backend_conn = rspamd_http_connection_new_client_socket (
session->ctx->http_ctx,
- bk_conn->backend_sock,
NULL,
proxy_backend_mirror_error_handler,
proxy_backend_mirror_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ bk_conn->backend_sock);
if (m->key) {
msg->peer_key = rspamd_pubkey_ref (m->key);
goto err; /* No fallback here */
}
- session->master_conn->backend_conn = rspamd_http_connection_new (
+ session->master_conn->backend_conn = rspamd_http_connection_new_client_socket (
session->ctx->http_ctx,
- session->master_conn->backend_sock,
NULL,
proxy_backend_master_error_handler,
proxy_backend_master_finish_handler,
RSPAMD_HTTP_CLIENT_SIMPLE,
- RSPAMD_HTTP_CLIENT);
+ session->master_conn->backend_sock);
session->master_conn->flags &= ~RSPAMD_BACKEND_CLOSED;
session->master_conn->parser_from_ref = backend->parser_from_ref;
session->master_conn->parser_to_ref = backend->parser_to_ref;
}
if (!ctx->milter) {
- session->client_conn = rspamd_http_connection_new (
+ session->client_conn = rspamd_http_connection_new_server (
ctx->http_ctx,
nfd,
NULL,
proxy_client_error_handler,
proxy_client_finish_handler,
- 0,
- RSPAMD_HTTP_SERVER);
+ 0);
if (ctx->key) {
rspamd_http_connection_set_key (session->client_conn, ctx->key);
http_opts = RSPAMD_HTTP_REQUIRE_ENCRYPTION;
}
- task->http_conn = rspamd_http_connection_new (
+ task->http_conn = rspamd_http_connection_new_server (
ctx->http_ctx,
nfd,
rspamd_worker_body_handler,
rspamd_worker_error_handler,
rspamd_worker_finish_handler,
- http_opts,
- RSPAMD_HTTP_SERVER);
+ http_opts);
rspamd_http_connection_set_max_size (task->http_conn, task->cfg->max_message);
worker->nconns++;
rspamd_mempool_add_destructor (task->task_pool,