Ejemplo n.º 1
0
static void
rspamd_server_accept (gint fd, short what, void *arg)
{
	struct event_base *ev_base = arg;
	struct rspamd_http_server_session *session;
	rspamd_inet_addr_t *addr;
	gint nfd;

	do {
		if ((nfd =
					 rspamd_accept_from_socket (fd, &addr)) == -1) {
			rspamd_fprintf (stderr, "accept failed: %s", strerror (errno));
			return;
		}
		/* Check for EAGAIN */
		if (nfd == 0) {
			return;
		}

		rspamd_inet_address_destroy (addr);
		session = g_slice_alloc (sizeof (*session));
		session->conn = rspamd_http_connection_new (NULL, rspamd_server_error,
				rspamd_server_finish, 0, RSPAMD_HTTP_SERVER, c);
		rspamd_http_connection_set_key (session->conn, server_key);
		rspamd_http_connection_read_message (session->conn,
				session,
				nfd,
				&io_tv,
				ev_base);
		session->reply = FALSE;
		session->fd = nfd;
		session->ev_base = ev_base;
	} while (nfd > 0);
}
Ejemplo n.º 2
0
static gint
rspamd_client_finish_handler (struct rspamd_http_connection *conn,
	struct rspamd_http_message *msg)
{
	struct rspamd_client_request *req =
		(struct rspamd_client_request *)conn->ud;
	struct rspamd_client_connection *c;
	struct ucl_parser *parser;
	GError *err;

	c = req->conn;

	if (!c->req_sent) {
		c->req_sent = TRUE;
		rspamd_http_connection_reset (c->http_conn);
		rspamd_http_connection_read_message (c->http_conn,
			c->req,
			c->fd,
			&c->timeout,
			c->ev_base);
		return 0;
	}
	else {
		if (rspamd_http_message_get_body (msg, NULL) == NULL || msg->code != 200) {
			err = g_error_new (RCLIENT_ERROR, msg->code, "HTTP error: %d, %.*s",
					msg->code,
					(gint)msg->status->len, msg->status->str);
			req->cb (c, msg, c->server_name->str, NULL, req->input, req->ud, err);
			g_error_free (err);

			return 0;
		}

		parser = ucl_parser_new (0);
		if (!ucl_parser_add_chunk (parser, msg->body_buf.begin, msg->body_buf.len)) {
			err = g_error_new (RCLIENT_ERROR, msg->code, "Cannot parse UCL: %s",
					ucl_parser_get_error (parser));
			ucl_parser_free (parser);
			req->cb (c, msg, c->server_name->str, NULL, req->input, req->ud, err);
			g_error_free (err);

			return 0;
		}

		req->cb (c, msg, c->server_name->str, ucl_parser_get_object (
				parser), req->input, req->ud, NULL);
		ucl_parser_free (parser);
	}

	return 0;
}
Ejemplo n.º 3
0
static gint
rspamd_client_finish_handler (struct rspamd_http_connection *conn,
                              struct rspamd_http_message *msg)
{
    struct rspamd_client_request *req =
        (struct rspamd_client_request *)conn->ud;
    struct rspamd_client_connection *c;
    struct ucl_parser *parser;
    GError *err;
    const rspamd_ftok_t *tok;

    c = req->conn;

    if (!c->req_sent) {
        c->req_sent = TRUE;
        rspamd_http_connection_reset (c->http_conn);
        rspamd_http_connection_read_message (c->http_conn,
                                             c->req,
                                             c->fd,
                                             &c->timeout,
                                             c->ev_base);
        return 0;
    }
    else {
        if (rspamd_http_message_get_body (msg, NULL) == NULL || msg->code != 200) {
            err = g_error_new (RCLIENT_ERROR, msg->code, "HTTP error: %d, %.*s",
                               msg->code,
                               (gint)msg->status->len, msg->status->str);
            req->cb (c, msg, c->server_name->str, NULL, req->input, req->ud, err);
            g_error_free (err);

            return 0;
        }

        tok = rspamd_http_message_find_header (msg, "compression");

        if (tok) {
            /* Need to uncompress */
            rspamd_ftok_t t;

            t.begin = "zstd";
            t.len = 4;

            if (rspamd_ftok_casecmp (tok, &t) == 0) {
                ZSTD_DStream *zstream;
                ZSTD_inBuffer zin;
                ZSTD_outBuffer zout;
                guchar *out;
                gsize outlen, r;

                zstream = ZSTD_createDStream ();
                ZSTD_initDStream (zstream);

                zin.pos = 0;
                zin.src = msg->body_buf.begin;
                zin.size = msg->body_buf.len;

                if ((outlen = ZSTD_getDecompressedSize (zin.src, zin.size)) == 0) {
                    outlen = ZSTD_DStreamOutSize ();
                }

                out = g_malloc (outlen);
                zout.dst = out;
                zout.pos = 0;
                zout.size = outlen;

                while (zin.pos < zin.size) {
                    r = ZSTD_decompressStream (zstream, &zout, &zin);

                    if (ZSTD_isError (r)) {
                        err = g_error_new (RCLIENT_ERROR, 500,
                                           "Decompression error: %s",
                                           ZSTD_getErrorName (r));
                        req->cb (c, msg, c->server_name->str, NULL,
                                 req->input, req->ud, err);
                        g_error_free (err);
                        ZSTD_freeDStream (zstream);
                        g_free (out);

                        return 0;
                    }

                    if (zout.pos == zout.size) {
                        /* We need to extend output buffer */
                        zout.size = zout.size * 1.5 + 1.0;
                        zout.dst = g_realloc (zout.dst, zout.size);
                    }
                }

                ZSTD_freeDStream (zstream);

                parser = ucl_parser_new (0);
                if (!ucl_parser_add_chunk (parser, zout.dst, zout.pos)) {
                    err = g_error_new (RCLIENT_ERROR, msg->code, "Cannot parse UCL: %s",
                                       ucl_parser_get_error (parser));
                    ucl_parser_free (parser);
                    req->cb (c, msg, c->server_name->str, NULL, req->input, req->ud, err);
                    g_error_free (err);
                    g_free (zout.dst);

                    return 0;
                }

                g_free (zout.dst);
            }
            else {
                err = g_error_new (RCLIENT_ERROR, 500,
                                   "Invalid compression method");
                req->cb (c, msg, c->server_name->str, NULL,
                         req->input, req->ud, err);
                g_error_free (err);

                return 0;
            }
        }
        else {
            parser = ucl_parser_new (0);
            if (!ucl_parser_add_chunk (parser, msg->body_buf.begin, msg->body_buf.len)) {
                err = g_error_new (RCLIENT_ERROR, msg->code, "Cannot parse UCL: %s",
                                   ucl_parser_get_error (parser));
                ucl_parser_free (parser);
                req->cb (c, msg, c->server_name->str, NULL, req->input, req->ud, err);
                g_error_free (err);

                return 0;
            }
        }

        req->cb (c, msg, c->server_name->str, ucl_parser_get_object (
                     parser), req->input, req->ud, NULL);
        ucl_parser_free (parser);
    }

    return 0;
}