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
每月 2,980 次下载
56KB
608 行
Rust ClamAV 客户端
一个简单的 ClamAV 客户端,用于将文件、内存数据和数据流发送到 clamd
进行病毒扫描。
它提供同步 API 以及针对 Tokio 和 async-std 的异步函数。
查看下面的 示例、集成测试 或 API 文档,以了解更多有关如何使用此库的信息。
安装
将以下内容添加到您的 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
函数,这些更新后的函数(如 ping
、scan_buffer
和 scan_file
)现在将连接类型(TCP 或 Unix 套接字)作为参数,有效地替代了 host_address
和 socket_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