예제 #1
0
파일: map.c 프로젝트: heartshare/rspamd
/**
 * Write HTTP request
 */
static void
write_http_request (struct http_callback_data *cbd)
{
	gchar datebuf[128];
	struct rspamd_http_message *msg;
	struct rspamd_map *map;

	map = cbd->map;

	if (cbd->fd != -1) {
		close (cbd->fd);
	}

	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->stage == map_load_file) {
			msg->url = rspamd_fstring_new_init (cbd->data->path, strlen (cbd->data->path));

			if (cbd->check &&
					cbd->data->last_checked != 0 && cbd->stage == map_load_file) {
				rspamd_http_date_format (datebuf, sizeof (datebuf),
						cbd->data->last_checked);
				rspamd_http_message_add_header (msg, "If-Modified-Since", datebuf);
			}
		}
		else if (cbd->stage == map_load_pubkey) {
			msg->url = rspamd_fstring_new_init (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_new_init (cbd->data->path, strlen (cbd->data->path));
			msg->url = rspamd_fstring_append (msg->url, ".sig", 4);
		}
		else {
			g_assert_not_reached ();
		}

		rspamd_http_connection_write_message (cbd->conn, msg, cbd->data->host,
				NULL, cbd, cbd->fd, &cbd->tv, cbd->ev_base);
		MAP_RETAIN (cbd, "http_callback_data");
	}
	else {
		msg_err_map ("cannot connect to %s: %s", cbd->data->host,
				strerror (errno));
		cbd->periodic->errored = TRUE;
	}
}
예제 #2
0
파일: map.c 프로젝트: Sp1l/rspamd
/**
 * Write HTTP request
 */
static void
write_http_request (struct http_callback_data *cbd)
{
	gchar datebuf[128];
	struct rspamd_http_message *msg;
	rspamd_mempool_t *pool;

	pool = cbd->map->pool;

	if (cbd->fd != -1) {
		close (cbd->fd);
	}

	cbd->fd = rspamd_inet_address_connect (cbd->addr, SOCK_STREAM, TRUE);

	if (cbd->fd != -1) {
		msg = rspamd_http_new_message (HTTP_REQUEST);

		if (cbd->stage == map_load_file) {
			msg->url = rspamd_fstring_new_init (cbd->data->path, strlen (cbd->data->path));

			if (cbd->data->last_checked != 0 && cbd->stage == map_load_file) {
				rspamd_http_date_format (datebuf, sizeof (datebuf),
						cbd->data->last_checked);
				rspamd_http_message_add_header (msg, "If-Modified-Since", datebuf);
			}
		}
		else if (cbd->stage == map_load_pubkey) {
			msg->url = rspamd_fstring_new_init (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_new_init (cbd->data->path, strlen (cbd->data->path));
			msg->url = rspamd_fstring_append (msg->url, ".sig", 4);
		}
		else {
			g_assert_not_reached ();
		}

		rspamd_http_connection_write_message (cbd->conn, msg, cbd->data->host,
				NULL, cbd, cbd->fd, &cbd->tv, cbd->ev_base);
		REF_RETAIN (cbd);
	}
	else {
		msg_err_pool ("cannot connect to %s: %s", cbd->data->host,
				strerror (errno));
	}
}
예제 #3
0
파일: map.c 프로젝트: skibbipl/rspamd
/**
 * Write HTTP request
 */
static void
write_http_request (struct http_callback_data *cbd)
{
    gchar datebuf[128];
    struct tm *tm;
    struct rspamd_http_message *msg;

    msg = rspamd_http_new_message (HTTP_REQUEST);

    msg->url = g_string_new (cbd->data->path);
    if (cbd->data->last_checked != 0) {
        tm = gmtime (&cbd->data->last_checked);
        strftime (datebuf, sizeof (datebuf), "%a, %d %b %Y %H:%M:%S %Z", tm);

        rspamd_http_message_add_header (msg, "If-Modified-Since", datebuf);
    }

    rspamd_http_connection_write_message (cbd->data->conn, msg, cbd->data->host,
                                          NULL, cbd, cbd->fd, &cbd->tv, cbd->ev_base);
}
예제 #4
0
gboolean
rspamd_client_command (struct rspamd_client_connection *conn,
	const gchar *command, GQueue *attrs,
	FILE *in, rspamd_client_callback cb,
	gpointer ud, GError **err)
{
	struct rspamd_client_request *req;
	struct rspamd_http_client_header *nh;
	gchar *p;
	gsize remain, old_len;
	GList *cur;
	GString *input = NULL;
	rspamd_fstring_t *body;

	req = g_slice_alloc0 (sizeof (struct rspamd_client_request));
	req->conn = conn;
	req->cb = cb;
	req->ud = ud;

	req->msg = rspamd_http_new_message (HTTP_REQUEST);
	if (conn->key) {
		req->msg->peer_key = rspamd_pubkey_ref (conn->key);
	}

	if (in != NULL) {
		/* Read input stream */
		input = g_string_sized_new (BUFSIZ);

		while (!feof (in)) {
			p = input->str + input->len;
			remain = input->allocated_len - input->len - 1;
			if (remain == 0) {
				old_len = input->len;
				g_string_set_size (input, old_len * 2);
				input->len = old_len;
				continue;
			}
			remain = fread (p, 1, remain, in);
			if (remain > 0) {
				input->len += remain;
				input->str[input->len] = '\0';
			}
		}
		if (ferror (in) != 0) {
			g_set_error (err, RCLIENT_ERROR, ferror (
					in), "input IO error: %s", strerror (ferror (in)));
			g_slice_free1 (sizeof (struct rspamd_client_request), req);
			g_string_free (input, TRUE);
			return FALSE;
		}

		body = rspamd_fstring_new_init (input->str, input->len);
		rspamd_http_message_set_body_from_fstring_steal (req->msg, body);
		req->input = input;
	}
	else {
		req->input = NULL;
	}

	/* Convert headers */
	cur = attrs->head;
	while (cur != NULL) {
		nh = cur->data;

		rspamd_http_message_add_header (req->msg, nh->name, nh->value);
		cur = g_list_next (cur);
	}

	req->msg->url = rspamd_fstring_append (req->msg->url, "/", 1);
	req->msg->url = rspamd_fstring_append (req->msg->url, command, strlen (command));

	conn->req = req;

	rspamd_http_connection_write_message (conn->http_conn, req->msg, NULL,
		"text/plain", req, conn->fd, &conn->timeout, conn->ev_base);

	return TRUE;
}
예제 #5
0
gboolean
rspamd_client_command (struct rspamd_client_connection *conn,
                       const gchar *command, GQueue *attrs,
                       FILE *in, rspamd_client_callback cb,
                       gpointer ud, gboolean compressed,
                       const gchar *comp_dictionary,
                       GError **err)
{
    struct rspamd_client_request *req;
    struct rspamd_http_client_header *nh;
    gchar *p;
    gsize remain, old_len;
    GList *cur;
    GString *input = NULL;
    rspamd_fstring_t *body;
    guint dict_id = 0;
    gsize dict_len = 0;
    void *dict = NULL;
    ZSTD_CCtx *zctx;

    req = g_slice_alloc0 (sizeof (struct rspamd_client_request));
    req->conn = conn;
    req->cb = cb;
    req->ud = ud;

    req->msg = rspamd_http_new_message (HTTP_REQUEST);
    if (conn->key) {
        req->msg->peer_key = rspamd_pubkey_ref (conn->key);
    }

    if (in != NULL) {
        /* Read input stream */
        input = g_string_sized_new (BUFSIZ);

        while (!feof (in)) {
            p = input->str + input->len;
            remain = input->allocated_len - input->len - 1;
            if (remain == 0) {
                old_len = input->len;
                g_string_set_size (input, old_len * 2);
                input->len = old_len;
                continue;
            }
            remain = fread (p, 1, remain, in);
            if (remain > 0) {
                input->len += remain;
                input->str[input->len] = '\0';
            }
        }
        if (ferror (in) != 0) {
            g_set_error (err, RCLIENT_ERROR, ferror (
                             in), "input IO error: %s", strerror (ferror (in)));
            g_slice_free1 (sizeof (struct rspamd_client_request), req);
            g_string_free (input, TRUE);
            return FALSE;
        }

        if (!compressed) {
            body = rspamd_fstring_new_init (input->str, input->len);
        }
        else {
            if (comp_dictionary) {
                dict = rspamd_file_xmap (comp_dictionary, PROT_READ, &dict_len);

                if (dict == NULL) {
                    g_set_error (err, RCLIENT_ERROR, errno,
                                 "cannot open dictionary %s: %s",
                                 comp_dictionary,
                                 strerror (errno));
                    g_slice_free1 (sizeof (struct rspamd_client_request), req);
                    g_string_free (input, TRUE);

                    return FALSE;
                }

                dict_id = ZDICT_getDictID (comp_dictionary, dict_len);

                if (dict_id == 0) {
                    g_set_error (err, RCLIENT_ERROR, errno,
                                 "cannot open dictionary %s: %s",
                                 comp_dictionary,
                                 strerror (errno));
                    g_slice_free1 (sizeof (struct rspamd_client_request), req);
                    g_string_free (input, TRUE);
                    munmap (dict, dict_len);

                    return FALSE;
                }
            }

            body = rspamd_fstring_sized_new (ZSTD_compressBound (input->len));
            zctx = ZSTD_createCCtx ();
            body->len = ZSTD_compress_usingDict (zctx, body->str, body->allocated,
                                                 input->str, input->len,
                                                 dict, dict_len,
                                                 1);

            munmap (dict, dict_len);

            if (ZSTD_isError (body->len)) {
                g_set_error (err, RCLIENT_ERROR, ferror (
                                 in), "compression error");
                g_slice_free1 (sizeof (struct rspamd_client_request), req);
                g_string_free (input, TRUE);
                rspamd_fstring_free (body);
                ZSTD_freeCCtx (zctx);

                return FALSE;
            }

            ZSTD_freeCCtx (zctx);
        }

        rspamd_http_message_set_body_from_fstring_steal (req->msg, body);
        req->input = input;
    }
    else {
        req->input = NULL;
    }

    /* Convert headers */
    cur = attrs->head;
    while (cur != NULL) {
        nh = cur->data;

        rspamd_http_message_add_header (req->msg, nh->name, nh->value);
        cur = g_list_next (cur);
    }

    if (compressed) {
        rspamd_http_message_add_header (req->msg, "Compression", "zstd");

        if (dict_id != 0) {
            gchar dict_str[32];

            rspamd_snprintf (dict_str, sizeof (dict_str), "%ud", dict_id);
            rspamd_http_message_add_header (req->msg, "Dictionary", dict_str);
        }
    }

    req->msg->url = rspamd_fstring_append (req->msg->url, "/", 1);
    req->msg->url = rspamd_fstring_append (req->msg->url, command, strlen (command));

    conn->req = req;

    if (compressed) {
        rspamd_http_connection_write_message (conn->http_conn, req->msg, NULL,
                                              "application/x-compressed", req, conn->fd,
                                              &conn->timeout, conn->ev_base);
    }
    else {
        rspamd_http_connection_write_message (conn->http_conn, req->msg, NULL,
                                              "text/plain", req, conn->fd, &conn->timeout, conn->ev_base);
    }

    return TRUE;
}