#clam-av #data-stream #async-await #tokio #async #client-send #clamd

clamav-client

支持可选 Tokio 和 async-std 的 ClamAV 客户端库

19 个版本 (4 个重大变更)

0.5.1 2024 年 3 月 21 日
0.5.0 2024 年 3 月 17 日
0.4.6 2024 年 3 月 6 日
0.4.5 2024 年 1 月 25 日
0.1.3 2021 年 5 月 16 日

#94 in Unix API

Download history 626/week @ 2024-04-22 549/week @ 2024-04-29 512/week @ 2024-05-06 564/week @ 2024-05-13 667/week @ 2024-05-20 437/week @ 2024-05-27 563/week @ 2024-06-03 702/week @ 2024-06-10 254/week @ 2024-06-24 2059/week @ 2024-07-01 2518/week @ 2024-07-08 2321/week @ 2024-07-15 33/week @ 2024-07-22 245/week @ 2024-07-29 40/week @ 2024-08-05

每月 2,980 次下载

MIT 许可证

56KB
608

Rust ClamAV 客户端

一个简单的 ClamAV 客户端,用于将文件、内存数据和数据流发送到 clamd 进行病毒扫描。

它提供同步 API 以及针对 Tokio 和 async-std 的异步函数。

查看下面的 示例集成测试API 文档,以了解更多有关如何使用此库的信息。

Workflow status

安装

将以下内容添加到您的 Cargo.toml

[dependencies]
clamav-client = "0.5.1"

要使用 async 函数,请添加以下内容到您的 Cargo.toml

[dependencies]
clamav-client = { version = "0.5.1", features = ["tokio"] }

要扫描 Tokio 流,启用 tokio-stream 功能并添加以下内容到您的 Cargo.toml

[dependencies]
clamav-client = { version = "0.5.1", features = ["tokio-stream"] }

通过启用 async-std 功能,也提供了对 async-std 的支持

[dependencies]
clamav-client = { version = "0.5.1", features = ["async-std"] }

迁移

迁移到 0.5.0

为了更通用的函数名,已经弃用了 *_socket*_tcp 函数,这些更新后的函数(如 pingscan_bufferscan_file)现在将连接类型(TCP 或 Unix 套接字)作为参数,有效地替代了 host_addresssocket_path 参数。

例如,

let clamd_host_address = "localhost:3310";
let result = clamav_client::scan_file_tcp("README.md", clamd_host_address, None);
assert!(result.is_ok());

变为

let clamd_tcp = clamav_client::Tcp{ host_address: "localhost:3310" };
let result = clamav_client::scan_file("README.md", clamd_tcp, None);
assert!(result.is_ok());

示例

用法

let clamd_tcp = clamav_client::Tcp{ host_address: "localhost:3310" };

// Ping clamd to make sure the server is available and accepting TCP connections
let clamd_available = match clamav_client::ping(clamd_tcp) {
    Ok(ping_response) => ping_response == clamav_client::PONG,
    Err(_) => false,
};

if !clamd_available {
    println!("Cannot ping clamd at {}", clamd_tcp.host_address);
    return;
}
assert!(clamd_available);

// Scan file for viruses
let file_path = "tests/data/eicar.txt";
let scan_file_response = clamav_client::scan_file(file_path, clamd_tcp, None).unwrap();
let file_clean = clamav_client::clean(&scan_file_response).unwrap();
if file_clean {
    println!("No virus found in {}", file_path);
} else {
    println!("The file {} is infected!", file_path);
}
assert!(!file_clean);

// Scan in-memory data for viruses
let buffer = br#"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"#;
let scan_buffer_response = clamav_client::scan_buffer(buffer, clamd_tcp, None).unwrap();
let data_clean = clamav_client::clean(&scan_buffer_response).unwrap();
if data_clean {
    println!("No virus found");
} else {
    println!("The data is infected!");
}
assert!(!data_clean);

用法 - 使用 tokio 进行异步操作

#[cfg(feature = "tokio-stream")]
tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(async {
    let clamd_tcp = clamav_client::tokio::Tcp{ host_address: "localhost:3310" };

    // Ping clamd asynchronously and await the result
    let clamd_available = match clamav_client::tokio::ping(clamd_tcp).await {
        Ok(ping_response) => ping_response == clamav_client::PONG,
        Err(_) => false,
    };

    if !clamd_available {
        println!("Cannot ping clamd at {}", clamd_tcp.host_address);
        return;
    }
    assert!(clamd_available);

    let file_path = "tests/data/eicar.txt";
    let buffer = br#"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"#;
    let file = tokio::fs::File::open(file_path).await.unwrap();
    let stream = tokio_util::io::ReaderStream::new(file);

    // Concurrently scan a file, a data buffer, and a file stream for viruses
    let (scan_file_result, scan_buffer_result, scan_stream_result) = tokio::join!(
        clamav_client::tokio::scan_file(file_path, clamd_tcp, None),
        clamav_client::tokio::scan_buffer(buffer, clamd_tcp, None),
        clamav_client::tokio::scan_stream(stream, clamd_tcp, None)
    );

    let scan_file_response = scan_file_result.unwrap();
    let file_clean = clamav_client::clean(&scan_file_response).unwrap();
    if file_clean {
        println!("No virus found in {}", file_path);
    } else {
        println!("The file {} is infected!", file_path);
    }
    assert!(!file_clean);

    let scan_buffer_response = scan_buffer_result.unwrap();
    let data_clean = clamav_client::clean(&scan_buffer_response).unwrap();
    if data_clean {
        println!("No virus found");
    } else {
        println!("The data buffer is infected!");
    }
    assert!(!data_clean);

    let scan_stream_response = scan_stream_result.unwrap();
    let stream_clean = clamav_client::clean(&scan_stream_response).unwrap();
    if stream_clean {
        println!("No virus found");
    } else {
        println!("The file stream is infected!");
    }
    assert!(!stream_clean);
})

用法 - 使用 async-std

#[cfg(feature = "async-std")]
async_std::task::block_on(async {
    let clamd_tcp = clamav_client::async_std::Tcp{ host_address: "localhost:3310" };

    // Ping clamd asynchronously and await the result
    let clamd_available = match clamav_client::async_std::ping(clamd_tcp).await {
        Ok(ping_response) => ping_response == clamav_client::PONG,
        Err(_) => false,
    };

    if !clamd_available {
        println!("Cannot ping clamd at {}", clamd_tcp.host_address);
        return;
    }
    assert!(clamd_available);

    // Scan a file for viruses
    let file_path = "tests/data/eicar.txt";
    let scan_file_result = clamav_client::async_std::scan_file(file_path, clamd_tcp, None).await;
    let scan_file_response = scan_file_result.unwrap();
    let file_clean = clamav_client::clean(&scan_file_response).unwrap();
    if file_clean {
        println!("No virus found in {}", file_path);
    } else {
        println!("The file {} is infected!", file_path);
    }
    assert!(!file_clean);
})

更多示例可以在测试中找到。

开发

本地测试

为了让测试通过,你应该按照以下方式启动clamd

clamd-F--config-file=clamd/clamd.conf

然后运行cargo test --all-features以覆盖所有测试。

实际上你如何启动clamd并不重要,只要你的配置与clamd.conf中的选项相同。

贡献

欢迎贡献!

贡献者

依赖

~0–11MB
~117K SLoC