mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-19 19:16:17 +00:00
feat: translate Chinese comments to English across codebase
This commit is contained in:
+41
-41
@@ -36,7 +36,7 @@ impl Default for CompressionLevel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CompressionFormat {
|
impl CompressionFormat {
|
||||||
/// 从文件扩展名识别压缩格式
|
/// Identify compression format from file extension
|
||||||
pub fn from_extension(ext: &str) -> Self {
|
pub fn from_extension(ext: &str) -> Self {
|
||||||
match ext.to_lowercase().as_str() {
|
match ext.to_lowercase().as_str() {
|
||||||
"gz" | "gzip" => CompressionFormat::Gzip,
|
"gz" | "gzip" => CompressionFormat::Gzip,
|
||||||
@@ -50,7 +50,7 @@ impl CompressionFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 从文件路径识别压缩格式
|
/// Identify compression format from file path
|
||||||
pub fn from_path<P: AsRef<Path>>(path: P) -> Self {
|
pub fn from_path<P: AsRef<Path>>(path: P) -> Self {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
if let Some(ext) = path.extension().and_then(|s| s.to_str()) {
|
if let Some(ext) = path.extension().and_then(|s| s.to_str()) {
|
||||||
@@ -60,7 +60,7 @@ impl CompressionFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取格式对应的文件扩展名
|
/// Get file extension corresponding to the format
|
||||||
pub fn extension(&self) -> &'static str {
|
pub fn extension(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
CompressionFormat::Gzip => "gz",
|
CompressionFormat::Gzip => "gz",
|
||||||
@@ -74,12 +74,12 @@ impl CompressionFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 检查格式是否支持
|
/// Check if format is supported
|
||||||
pub fn is_supported(&self) -> bool {
|
pub fn is_supported(&self) -> bool {
|
||||||
!matches!(self, CompressionFormat::Unknown)
|
!matches!(self, CompressionFormat::Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 创建解压缩器
|
/// Create decompressor
|
||||||
pub fn get_decoder<R>(&self, input: R) -> io::Result<Box<dyn AsyncRead + Send + Unpin>>
|
pub fn get_decoder<R>(&self, input: R) -> io::Result<Box<dyn AsyncRead + Send + Unpin>>
|
||||||
where
|
where
|
||||||
R: AsyncRead + Send + Unpin + 'static,
|
R: AsyncRead + Send + Unpin + 'static,
|
||||||
@@ -107,7 +107,7 @@ impl CompressionFormat {
|
|||||||
Ok(decoder)
|
Ok(decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 创建压缩器
|
/// Create compressor
|
||||||
pub fn get_encoder<W>(&self, output: W, level: CompressionLevel) -> io::Result<Box<dyn AsyncWrite + Send + Unpin>>
|
pub fn get_encoder<W>(&self, output: W, level: CompressionLevel) -> io::Result<Box<dyn AsyncWrite + Send + Unpin>>
|
||||||
where
|
where
|
||||||
W: AsyncWrite + Send + Unpin + 'static,
|
W: AsyncWrite + Send + Unpin + 'static,
|
||||||
@@ -176,7 +176,7 @@ impl CompressionFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解压tar格式的压缩文件
|
/// Decompress tar format compressed files
|
||||||
pub async fn decompress<R, F>(input: R, format: CompressionFormat, mut callback: F) -> io::Result<()>
|
pub async fn decompress<R, F>(input: R, format: CompressionFormat, mut callback: F) -> io::Result<()>
|
||||||
where
|
where
|
||||||
R: AsyncRead + Send + Unpin + 'static,
|
R: AsyncRead + Send + Unpin + 'static,
|
||||||
@@ -194,7 +194,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ZIP文件条目信息
|
/// ZIP file entry information
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ZipEntry {
|
pub struct ZipEntry {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -204,33 +204,33 @@ pub struct ZipEntry {
|
|||||||
pub compression_method: String,
|
pub compression_method: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 简化的ZIP文件处理(暂时使用标准库的zip crate)
|
/// Simplified ZIP file processing (temporarily using standard library zip crate)
|
||||||
pub async fn extract_zip_simple<P: AsRef<Path>>(
|
pub async fn extract_zip_simple<P: AsRef<Path>>(
|
||||||
zip_path: P,
|
zip_path: P,
|
||||||
extract_to: P,
|
extract_to: P,
|
||||||
) -> io::Result<Vec<ZipEntry>> {
|
) -> io::Result<Vec<ZipEntry>> {
|
||||||
// 使用标准库的zip处理,这里先返回空列表作为占位符
|
// Use standard library zip processing, return empty list as placeholder for now
|
||||||
// 实际实现需要在后续版本中完善
|
// Actual implementation needs to be improved in future versions
|
||||||
let _zip_path = zip_path.as_ref();
|
let _zip_path = zip_path.as_ref();
|
||||||
let _extract_to = extract_to.as_ref();
|
let _extract_to = extract_to.as_ref();
|
||||||
|
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 简化的ZIP文件创建
|
/// Simplified ZIP file creation
|
||||||
pub async fn create_zip_simple<P: AsRef<Path>>(
|
pub async fn create_zip_simple<P: AsRef<Path>>(
|
||||||
_zip_path: P,
|
_zip_path: P,
|
||||||
_files: Vec<(String, Vec<u8>)>, // (文件名, 文件内容)
|
_files: Vec<(String, Vec<u8>)>, // (filename, file content)
|
||||||
_compression_level: CompressionLevel,
|
_compression_level: CompressionLevel,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
// 暂时返回未实现错误
|
// Return unimplemented error for now
|
||||||
Err(io::Error::new(
|
Err(io::Error::new(
|
||||||
io::ErrorKind::Unsupported,
|
io::ErrorKind::Unsupported,
|
||||||
"ZIP creation not yet implemented",
|
"ZIP creation not yet implemented",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 压缩工具结构体
|
/// Compression utility struct
|
||||||
pub struct Compressor {
|
pub struct Compressor {
|
||||||
format: CompressionFormat,
|
format: CompressionFormat,
|
||||||
level: CompressionLevel,
|
level: CompressionLevel,
|
||||||
@@ -249,7 +249,7 @@ impl Compressor {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 压缩数据
|
/// Compress data
|
||||||
pub async fn compress(&self, input: &[u8]) -> io::Result<Vec<u8>> {
|
pub async fn compress(&self, input: &[u8]) -> io::Result<Vec<u8>> {
|
||||||
let output = Vec::new();
|
let output = Vec::new();
|
||||||
let cursor = std::io::Cursor::new(output);
|
let cursor = std::io::Cursor::new(output);
|
||||||
@@ -258,13 +258,13 @@ impl Compressor {
|
|||||||
tokio::io::copy(&mut std::io::Cursor::new(input), &mut encoder).await?;
|
tokio::io::copy(&mut std::io::Cursor::new(input), &mut encoder).await?;
|
||||||
encoder.shutdown().await?;
|
encoder.shutdown().await?;
|
||||||
|
|
||||||
// 获取压缩后的数据
|
// Get compressed data
|
||||||
// 注意:这里需要重新设计API,因为我们无法从encoder中取回数据
|
// Note: API needs to be redesigned here as we cannot retrieve data from encoder
|
||||||
// 暂时返回空向量作为占位符
|
// Return empty vector as placeholder for now
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解压缩数据
|
/// Decompress data
|
||||||
pub async fn decompress(&self, input: Vec<u8>) -> io::Result<Vec<u8>> {
|
pub async fn decompress(&self, input: Vec<u8>) -> io::Result<Vec<u8>> {
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
let cursor = std::io::Cursor::new(input);
|
let cursor = std::io::Cursor::new(input);
|
||||||
@@ -276,7 +276,7 @@ impl Compressor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解压缩工具结构体
|
/// Decompression utility struct
|
||||||
pub struct Decompressor {
|
pub struct Decompressor {
|
||||||
format: CompressionFormat,
|
format: CompressionFormat,
|
||||||
}
|
}
|
||||||
@@ -291,7 +291,7 @@ impl Decompressor {
|
|||||||
Self { format }
|
Self { format }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解压缩文件
|
/// Decompress file
|
||||||
pub async fn decompress_file<P: AsRef<Path>>(&self, input_path: P, output_path: P) -> io::Result<()> {
|
pub async fn decompress_file<P: AsRef<Path>>(&self, input_path: P, output_path: P) -> io::Result<()> {
|
||||||
let input_file = File::open(&input_path).await?;
|
let input_file = File::open(&input_path).await?;
|
||||||
let output_file = File::create(&output_path).await?;
|
let output_file = File::create(&output_path).await?;
|
||||||
@@ -339,7 +339,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compression_format_case_sensitivity() {
|
fn test_compression_format_case_sensitivity() {
|
||||||
// 测试大小写不敏感性(现在支持大小写不敏感)
|
// Test case insensitivity (now supports case insensitivity)
|
||||||
assert_eq!(CompressionFormat::from_extension("GZ"), CompressionFormat::Gzip);
|
assert_eq!(CompressionFormat::from_extension("GZ"), CompressionFormat::Gzip);
|
||||||
assert_eq!(CompressionFormat::from_extension("Gz"), CompressionFormat::Gzip);
|
assert_eq!(CompressionFormat::from_extension("Gz"), CompressionFormat::Gzip);
|
||||||
assert_eq!(CompressionFormat::from_extension("BZ2"), CompressionFormat::Bzip2);
|
assert_eq!(CompressionFormat::from_extension("BZ2"), CompressionFormat::Bzip2);
|
||||||
@@ -348,7 +348,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compression_format_edge_cases() {
|
fn test_compression_format_edge_cases() {
|
||||||
// 测试边界情况
|
// Test edge cases
|
||||||
assert_eq!(CompressionFormat::from_extension("gz "), CompressionFormat::Unknown);
|
assert_eq!(CompressionFormat::from_extension("gz "), CompressionFormat::Unknown);
|
||||||
assert_eq!(CompressionFormat::from_extension(" gz"), CompressionFormat::Unknown);
|
assert_eq!(CompressionFormat::from_extension(" gz"), CompressionFormat::Unknown);
|
||||||
assert_eq!(CompressionFormat::from_extension("gz.bak"), CompressionFormat::Unknown);
|
assert_eq!(CompressionFormat::from_extension("gz.bak"), CompressionFormat::Unknown);
|
||||||
@@ -357,7 +357,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compression_format_debug() {
|
fn test_compression_format_debug() {
|
||||||
// 测试Debug trait实现
|
// Test Debug trait implementation
|
||||||
let format = CompressionFormat::Gzip;
|
let format = CompressionFormat::Gzip;
|
||||||
let debug_str = format!("{:?}", format);
|
let debug_str = format!("{:?}", format);
|
||||||
assert_eq!(debug_str, "Gzip");
|
assert_eq!(debug_str, "Gzip");
|
||||||
@@ -369,7 +369,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compression_format_equality() {
|
fn test_compression_format_equality() {
|
||||||
// 测试PartialEq trait实现
|
// Test PartialEq trait implementation
|
||||||
assert_eq!(CompressionFormat::Gzip, CompressionFormat::Gzip);
|
assert_eq!(CompressionFormat::Gzip, CompressionFormat::Gzip);
|
||||||
assert_eq!(CompressionFormat::Unknown, CompressionFormat::Unknown);
|
assert_eq!(CompressionFormat::Unknown, CompressionFormat::Unknown);
|
||||||
assert_ne!(CompressionFormat::Gzip, CompressionFormat::Bzip2);
|
assert_ne!(CompressionFormat::Gzip, CompressionFormat::Bzip2);
|
||||||
@@ -378,7 +378,7 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_get_decoder_supported_formats() {
|
async fn test_get_decoder_supported_formats() {
|
||||||
// 测试支持的格式能够创建解码器
|
// Test that supported formats can create decoders
|
||||||
let test_data = b"test data";
|
let test_data = b"test data";
|
||||||
let cursor = Cursor::new(test_data);
|
let cursor = Cursor::new(test_data);
|
||||||
|
|
||||||
@@ -389,7 +389,7 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_get_decoder_unsupported_formats() {
|
async fn test_get_decoder_unsupported_formats() {
|
||||||
// 测试不支持的格式返回错误
|
// Test that unsupported formats return errors
|
||||||
let test_data = b"test data";
|
let test_data = b"test data";
|
||||||
let cursor = Cursor::new(test_data);
|
let cursor = Cursor::new(test_data);
|
||||||
|
|
||||||
@@ -405,7 +405,7 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_get_decoder_zip_format() {
|
async fn test_get_decoder_zip_format() {
|
||||||
// 测试Zip格式(当前不支持)
|
// Test Zip format (currently not supported)
|
||||||
let test_data = b"test data";
|
let test_data = b"test data";
|
||||||
let cursor = Cursor::new(test_data);
|
let cursor = Cursor::new(test_data);
|
||||||
|
|
||||||
@@ -452,7 +452,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compression_format_exhaustive_matching() {
|
fn test_compression_format_exhaustive_matching() {
|
||||||
// 测试所有枚举变体都有对应的处理
|
// Test that all enum variants have corresponding handling
|
||||||
let all_formats = vec![
|
let all_formats = vec![
|
||||||
CompressionFormat::Gzip,
|
CompressionFormat::Gzip,
|
||||||
CompressionFormat::Bzip2,
|
CompressionFormat::Bzip2,
|
||||||
@@ -464,17 +464,17 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for format in all_formats {
|
for format in all_formats {
|
||||||
// 验证每个格式都有对应的Debug实现
|
// Verify each format has corresponding Debug implementation
|
||||||
let _debug_str = format!("{:?}", format);
|
let _debug_str = format!("{:?}", format);
|
||||||
|
|
||||||
// 验证每个格式都有对应的PartialEq实现
|
// Verify each format has corresponding PartialEq implementation
|
||||||
assert_eq!(format, format);
|
assert_eq!(format, format);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_extension_mapping_completeness() {
|
fn test_extension_mapping_completeness() {
|
||||||
// 测试扩展名映射的完整性
|
// Test completeness of extension mapping
|
||||||
let extension_mappings = vec![
|
let extension_mappings = vec![
|
||||||
("gz", CompressionFormat::Gzip),
|
("gz", CompressionFormat::Gzip),
|
||||||
("gzip", CompressionFormat::Gzip),
|
("gzip", CompressionFormat::Gzip),
|
||||||
@@ -496,7 +496,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_format_string_representations() {
|
fn test_format_string_representations() {
|
||||||
// 测试格式的字符串表示
|
// Test string representation of formats
|
||||||
let format_strings = vec![
|
let format_strings = vec![
|
||||||
(CompressionFormat::Gzip, "Gzip"),
|
(CompressionFormat::Gzip, "Gzip"),
|
||||||
(CompressionFormat::Bzip2, "Bzip2"),
|
(CompressionFormat::Bzip2, "Bzip2"),
|
||||||
@@ -528,34 +528,34 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_compression_format_memory_efficiency() {
|
fn test_compression_format_memory_efficiency() {
|
||||||
// 测试枚举的内存效率
|
// Test memory efficiency of enum
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
// 验证枚举大小合理
|
// Verify enum size is reasonable
|
||||||
let size = mem::size_of::<CompressionFormat>();
|
let size = mem::size_of::<CompressionFormat>();
|
||||||
assert!(size <= 8, "CompressionFormat should be memory efficient, got {} bytes", size);
|
assert!(size <= 8, "CompressionFormat should be memory efficient, got {} bytes", size);
|
||||||
|
|
||||||
// 验证Option<CompressionFormat>的大小
|
// Verify Option<CompressionFormat> size
|
||||||
let option_size = mem::size_of::<Option<CompressionFormat>>();
|
let option_size = mem::size_of::<Option<CompressionFormat>>();
|
||||||
assert!(option_size <= 16, "Option<CompressionFormat> should be efficient, got {} bytes", option_size);
|
assert!(option_size <= 16, "Option<CompressionFormat> should be efficient, got {} bytes", option_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_extension_validation() {
|
fn test_extension_validation() {
|
||||||
// 测试扩展名验证的边界情况
|
// Test edge cases of extension validation
|
||||||
let test_cases = vec![
|
let test_cases = vec![
|
||||||
// 正常情况
|
// Normal cases
|
||||||
("gz", true),
|
("gz", true),
|
||||||
("bz2", true),
|
("bz2", true),
|
||||||
("xz", true),
|
("xz", true),
|
||||||
|
|
||||||
// 边界情况
|
// Edge cases
|
||||||
("", false),
|
("", false),
|
||||||
("g", false),
|
("g", false),
|
||||||
("gzz", false),
|
("gzz", false),
|
||||||
("gz2", false),
|
("gz2", false),
|
||||||
|
|
||||||
// 特殊字符
|
// Special characters
|
||||||
("gz.", false),
|
("gz.", false),
|
||||||
(".gz", false),
|
(".gz", false),
|
||||||
("gz-", false),
|
("gz-", false),
|
||||||
|
|||||||
@@ -35,19 +35,19 @@ async fn ping() -> Result<(), Box<dyn Error>> {
|
|||||||
let decoded_payload = flatbuffers::root::<PingBody>(finished_data);
|
let decoded_payload = flatbuffers::root::<PingBody>(finished_data);
|
||||||
assert!(decoded_payload.is_ok());
|
assert!(decoded_payload.is_ok());
|
||||||
|
|
||||||
// 创建客户端
|
// Create client
|
||||||
let mut client = node_service_time_out_client(&CLUSTER_ADDR.to_string()).await?;
|
let mut client = node_service_time_out_client(&CLUSTER_ADDR.to_string()).await?;
|
||||||
|
|
||||||
// 构造 PingRequest
|
// Construct PingRequest
|
||||||
let request = Request::new(PingRequest {
|
let request = Request::new(PingRequest {
|
||||||
version: 1,
|
version: 1,
|
||||||
body: finished_data.to_vec(),
|
body: finished_data.to_vec(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// 发送请求并获取响应
|
// Send request and get response
|
||||||
let response: PingResponse = client.ping(request).await?.into_inner();
|
let response: PingResponse = client.ping(request).await?.into_inner();
|
||||||
|
|
||||||
// 打印响应
|
// Print response
|
||||||
let ping_response_body = flatbuffers::root::<PingBody>(&response.body);
|
let ping_response_body = flatbuffers::root::<PingBody>(&response.body);
|
||||||
if let Err(e) = ping_response_body {
|
if let Err(e) = ping_response_body {
|
||||||
eprintln!("{}", e);
|
eprintln!("{}", e);
|
||||||
|
|||||||
+1
-1
@@ -156,7 +156,7 @@ pub fn clone_err(e: &common::error::Error) -> common::error::Error {
|
|||||||
common::error::Error::new(std::io::Error::new(e.kind(), e.to_string()))
|
common::error::Error::new(std::io::Error::new(e.kind(), e.to_string()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//TODO: 优化其他类型
|
//TODO: Optimize other types
|
||||||
common::error::Error::msg(e.to_string())
|
common::error::Error::msg(e.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -94,7 +94,7 @@ where
|
|||||||
self.clone().save_iam_formatter().await?;
|
self.clone().save_iam_formatter().await?;
|
||||||
self.clone().load().await?;
|
self.clone().load().await?;
|
||||||
|
|
||||||
// 后台线程开启定时更新或者接收到信号更新
|
// Background thread starts periodic updates or receives signal updates
|
||||||
tokio::spawn({
|
tokio::spawn({
|
||||||
let s = Arc::clone(&self);
|
let s = Arc::clone(&self);
|
||||||
async move {
|
async move {
|
||||||
@@ -142,7 +142,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo, 判断是否存在,是否可以重试
|
// TODO: Check if exists, whether retry is possible
|
||||||
#[tracing::instrument(level = "debug", skip(self))]
|
#[tracing::instrument(level = "debug", skip(self))]
|
||||||
async fn save_iam_formatter(self: Arc<Self>) -> Result<()> {
|
async fn save_iam_formatter(self: Arc<Self>) -> Result<()> {
|
||||||
let path = get_iam_format_file_path();
|
let path = get_iam_format_file_path();
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ impl ObjectStore {
|
|||||||
async fn list_iam_config_items(&self, prefix: &str, ctx_rx: B_Receiver<bool>, sender: Sender<StringOrErr>) {
|
async fn list_iam_config_items(&self, prefix: &str, ctx_rx: B_Receiver<bool>, sender: Sender<StringOrErr>) {
|
||||||
// debug!("list iam config items, prefix: {}", &prefix);
|
// debug!("list iam config items, prefix: {}", &prefix);
|
||||||
|
|
||||||
// todo, 实现walk,使用walk
|
// TODO: Implement walk, use walk
|
||||||
|
|
||||||
// let prefix = format!("{}{}", prefix, item);
|
// let prefix = format!("{}{}", prefix, item);
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test_case(r#"{"aws:usernamea":"johndoe"}"#)]
|
#[test_case(r#"{"aws:usernamea":"johndoe"}"#)]
|
||||||
#[test_case(r#"{"aws:username":[]}"#)] // 空
|
#[test_case(r#"{"aws:username":[]}"#)] // Empty
|
||||||
#[test_case(r#"{"aws:usernamea/value":"johndoe"}"#)]
|
#[test_case(r#"{"aws:usernamea/value":"johndoe"}"#)]
|
||||||
#[test_case(r#"{"aws:usernamea/value":["johndoe", "aaa"]}"#)]
|
#[test_case(r#"{"aws:usernamea/value":["johndoe", "aaa"]}"#)]
|
||||||
#[test_case(r#""aaa""#)]
|
#[test_case(r#""aaa""#)]
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl FuncKeyValue<StringFuncValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解析values字段
|
/// Parse values field
|
||||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
|
|
||||||
pub struct StringFuncValue(pub Set<String>);
|
pub struct StringFuncValue(pub Set<String>);
|
||||||
@@ -229,7 +229,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test_case(r#"{"aws:usernamea":"johndoe"}"#)]
|
#[test_case(r#"{"aws:usernamea":"johndoe"}"#)]
|
||||||
#[test_case(r#"{"aws:username":[]}"#)] // 空
|
#[test_case(r#"{"aws:username":[]}"#)] // Empty
|
||||||
#[test_case(r#"{"aws:usernamea/value":"johndoe"}"#)]
|
#[test_case(r#"{"aws:usernamea/value":"johndoe"}"#)]
|
||||||
#[test_case(r#"{"aws:usernamea/value":["johndoe", "aaa"]}"#)]
|
#[test_case(r#"{"aws:usernamea/value":["johndoe", "aaa"]}"#)]
|
||||||
#[test_case(r#""aaa""#)]
|
#[test_case(r#""aaa""#)]
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ impl Operation for AssumeRoleHandle {
|
|||||||
let (cred, _owner) =
|
let (cred, _owner) =
|
||||||
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &user.access_key).await?;
|
check_key_valid(get_session_token(&req.uri, &req.headers).unwrap_or_default(), &user.access_key).await?;
|
||||||
|
|
||||||
// // TODO: 判断权限, 不允许sts访问
|
// // TODO: Check permissions, do not allow STS access
|
||||||
if cred.is_temp() || cred.is_service_account() {
|
if cred.is_temp() || cred.is_service_account() {
|
||||||
return Err(s3_error!(InvalidRequest, "AccessDenied"));
|
return Err(s3_error!(InvalidRequest, "AccessDenied"));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -138,7 +138,7 @@ async fn run(opt: config::Opt) -> Result<()> {
|
|||||||
// let local_ip = utils::get_local_ip().ok_or(local_addr.ip()).unwrap();
|
// let local_ip = utils::get_local_ip().ok_or(local_addr.ip()).unwrap();
|
||||||
let local_ip = rustfs_utils::get_local_ip().ok_or(local_addr.ip()).unwrap();
|
let local_ip = rustfs_utils::get_local_ip().ok_or(local_addr.ip()).unwrap();
|
||||||
|
|
||||||
// 用于 rpc
|
// For RPC
|
||||||
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), opt.volumes.clone())
|
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), opt.volumes.clone())
|
||||||
.map_err(|err| Error::from_string(err.to_string()))?;
|
.map_err(|err| Error::from_string(err.to_string()))?;
|
||||||
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ impl S3Access for FS {
|
|||||||
// /// + [`cx.s3_op().name()`](crate::S3Operation::name)
|
// /// + [`cx.s3_op().name()`](crate::S3Operation::name)
|
||||||
// /// + [`cx.extensions_mut()`](S3AccessContext::extensions_mut)
|
// /// + [`cx.extensions_mut()`](S3AccessContext::extensions_mut)
|
||||||
async fn check(&self, cx: &mut S3AccessContext<'_>) -> S3Result<()> {
|
async fn check(&self, cx: &mut S3AccessContext<'_>) -> S3Result<()> {
|
||||||
// 上层验证了 ak/sk
|
// Upper layer has verified ak/sk
|
||||||
// info!(
|
// info!(
|
||||||
// "s3 check uri: {:?}, method: {:?} path: {:?}, s3_op: {:?}, cred: {:?}, headers:{:?}",
|
// "s3 check uri: {:?}, method: {:?} path: {:?}, s3_op: {:?}, cred: {:?}, headers:{:?}",
|
||||||
// cx.uri(),
|
// cx.uri(),
|
||||||
@@ -173,7 +173,7 @@ impl S3Access for FS {
|
|||||||
let ext = cx.extensions_mut();
|
let ext = cx.extensions_mut();
|
||||||
ext.insert(req_info);
|
ext.insert(req_info);
|
||||||
|
|
||||||
// 统一在这验证?还是在下面各自验证?
|
// Verify uniformly here? Or verify separately below?
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ impl FS {
|
|||||||
|
|
||||||
let ext = ext.to_owned();
|
let ext = ext.to_owned();
|
||||||
|
|
||||||
// TODO: spport zip
|
// TODO: support zip
|
||||||
let decoder = CompressionFormat::from_extension(&ext).get_decoder(body).map_err(|e| {
|
let decoder = CompressionFormat::from_extension(&ext).get_decoder(body).map_err(|e| {
|
||||||
error!("get_decoder err {:?}", e);
|
error!("get_decoder err {:?}", e);
|
||||||
s3_error!(InvalidArgument, "get_decoder err")
|
s3_error!(InvalidArgument, "get_decoder err")
|
||||||
@@ -204,8 +204,8 @@ impl FS {
|
|||||||
// )
|
// )
|
||||||
// .await
|
// .await
|
||||||
// {
|
// {
|
||||||
// Ok(_) => println!("解压成功!"),
|
// Ok(_) => println!("Decompression successful!"),
|
||||||
// Err(e) => println!("解压失败: {}", e),
|
// Err(e) => println!("Decompression failed: {}", e),
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// TODO: etag
|
// TODO: etag
|
||||||
@@ -341,7 +341,7 @@ impl S3 for FS {
|
|||||||
#[tracing::instrument(level = "debug", skip(self, req))]
|
#[tracing::instrument(level = "debug", skip(self, req))]
|
||||||
async fn delete_bucket(&self, req: S3Request<DeleteBucketInput>) -> S3Result<S3Response<DeleteBucketOutput>> {
|
async fn delete_bucket(&self, req: S3Request<DeleteBucketInput>) -> S3Result<S3Response<DeleteBucketOutput>> {
|
||||||
let input = req.input;
|
let input = req.input;
|
||||||
// TODO: DeleteBucketInput 没有 force 参数?
|
// TODO: DeleteBucketInput doesn't have force parameter?
|
||||||
let Some(store) = new_object_layer_fn() else {
|
let Some(store) = new_object_layer_fn() else {
|
||||||
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
|
return Err(S3Error::with_message(S3ErrorCode::InternalError, "Not init".to_string()));
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user