mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-29 01:29:00 +00:00
48a9707110
* fix: add tokio-test
* fix: "called `unwrap` on `v` after checking its variant with `is_some`"
= help: try using `if let` or `match`
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
= note: `-D clippy::unnecessary-unwrap` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_unwrap)]`
* fmt
* set toolchain 1.88.0
* fmt
* fix: cliip
198 lines
6.9 KiB
Rust
198 lines
6.9 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use crate::base64;
|
|
use http::header::{HeaderMap, HeaderValue};
|
|
|
|
use crate::Crc64Nvme;
|
|
use crate::{CRC_32_C_NAME, CRC_32_NAME, CRC_64_NVME_NAME, Checksum, Crc32, Crc32c, Md5, SHA_1_NAME, SHA_256_NAME, Sha1, Sha256};
|
|
|
|
pub const CRC_32_HEADER_NAME: &str = "x-amz-checksum-crc32";
|
|
pub const CRC_32_C_HEADER_NAME: &str = "x-amz-checksum-crc32c";
|
|
pub const SHA_1_HEADER_NAME: &str = "x-amz-checksum-sha1";
|
|
pub const SHA_256_HEADER_NAME: &str = "x-amz-checksum-sha256";
|
|
pub const CRC_64_NVME_HEADER_NAME: &str = "x-amz-checksum-crc64nvme";
|
|
|
|
#[allow(dead_code)]
|
|
pub(crate) static MD5_HEADER_NAME: &str = "content-md5";
|
|
|
|
pub const CHECKSUM_ALGORITHMS_IN_PRIORITY_ORDER: [&str; 5] =
|
|
[CRC_64_NVME_NAME, CRC_32_C_NAME, CRC_32_NAME, SHA_1_NAME, SHA_256_NAME];
|
|
|
|
pub trait HttpChecksum: Checksum + Send + Sync {
|
|
fn headers(self: Box<Self>) -> HeaderMap<HeaderValue> {
|
|
let mut header_map = HeaderMap::new();
|
|
header_map.insert(self.header_name(), self.header_value());
|
|
|
|
header_map
|
|
}
|
|
|
|
fn header_name(&self) -> &'static str;
|
|
|
|
fn header_value(self: Box<Self>) -> HeaderValue {
|
|
let hash = self.finalize();
|
|
HeaderValue::from_str(&base64::encode(&hash[..])).expect("base64 encoded bytes are always valid header values")
|
|
}
|
|
|
|
fn size(&self) -> u64 {
|
|
let trailer_name_size_in_bytes = self.header_name().len();
|
|
let base64_encoded_checksum_size_in_bytes = base64::encoded_length(Checksum::size(self) as usize);
|
|
|
|
let size = trailer_name_size_in_bytes + ":".len() + base64_encoded_checksum_size_in_bytes;
|
|
|
|
size as u64
|
|
}
|
|
}
|
|
|
|
impl HttpChecksum for Crc32 {
|
|
fn header_name(&self) -> &'static str {
|
|
CRC_32_HEADER_NAME
|
|
}
|
|
}
|
|
|
|
impl HttpChecksum for Crc32c {
|
|
fn header_name(&self) -> &'static str {
|
|
CRC_32_C_HEADER_NAME
|
|
}
|
|
}
|
|
|
|
impl HttpChecksum for Crc64Nvme {
|
|
fn header_name(&self) -> &'static str {
|
|
CRC_64_NVME_HEADER_NAME
|
|
}
|
|
}
|
|
|
|
impl HttpChecksum for Sha1 {
|
|
fn header_name(&self) -> &'static str {
|
|
SHA_1_HEADER_NAME
|
|
}
|
|
}
|
|
|
|
impl HttpChecksum for Sha256 {
|
|
fn header_name(&self) -> &'static str {
|
|
SHA_256_HEADER_NAME
|
|
}
|
|
}
|
|
|
|
impl HttpChecksum for Md5 {
|
|
fn header_name(&self) -> &'static str {
|
|
MD5_HEADER_NAME
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::base64;
|
|
use bytes::Bytes;
|
|
|
|
use crate::{CRC_32_C_NAME, CRC_32_NAME, CRC_64_NVME_NAME, ChecksumAlgorithm, SHA_1_NAME, SHA_256_NAME};
|
|
|
|
use super::HttpChecksum;
|
|
|
|
#[test]
|
|
fn test_trailer_length_of_crc32_checksum_body() {
|
|
let checksum = CRC_32_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
let expected_size = 29;
|
|
let actual_size = HttpChecksum::size(&*checksum);
|
|
assert_eq!(expected_size, actual_size)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_value_of_crc32_checksum_body() {
|
|
let checksum = CRC_32_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
// The CRC32 of an empty string is all zeroes
|
|
let expected_value = Bytes::from_static(b"\0\0\0\0");
|
|
let expected_value = base64::encode(&expected_value);
|
|
let actual_value = checksum.header_value();
|
|
assert_eq!(expected_value, actual_value)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_length_of_crc32c_checksum_body() {
|
|
let checksum = CRC_32_C_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
let expected_size = 30;
|
|
let actual_size = HttpChecksum::size(&*checksum);
|
|
assert_eq!(expected_size, actual_size)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_value_of_crc32c_checksum_body() {
|
|
let checksum = CRC_32_C_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
// The CRC32C of an empty string is all zeroes
|
|
let expected_value = Bytes::from_static(b"\0\0\0\0");
|
|
let expected_value = base64::encode(&expected_value);
|
|
let actual_value = checksum.header_value();
|
|
assert_eq!(expected_value, actual_value)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_length_of_crc64nvme_checksum_body() {
|
|
let checksum = CRC_64_NVME_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
let expected_size = 37;
|
|
let actual_size = HttpChecksum::size(&*checksum);
|
|
assert_eq!(expected_size, actual_size)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_value_of_crc64nvme_checksum_body() {
|
|
let checksum = CRC_64_NVME_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
// The CRC64NVME of an empty string is all zeroes
|
|
let expected_value = Bytes::from_static(b"\0\0\0\0\0\0\0\0");
|
|
let expected_value = base64::encode(&expected_value);
|
|
let actual_value = checksum.header_value();
|
|
assert_eq!(expected_value, actual_value)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_length_of_sha1_checksum_body() {
|
|
let checksum = SHA_1_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
let expected_size = 48;
|
|
let actual_size = HttpChecksum::size(&*checksum);
|
|
assert_eq!(expected_size, actual_size)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_value_of_sha1_checksum_body() {
|
|
let checksum = SHA_1_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
// The SHA1 of an empty string is da39a3ee5e6b4b0d3255bfef95601890afd80709
|
|
let expected_value = Bytes::from_static(&[
|
|
0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07,
|
|
0x09,
|
|
]);
|
|
let expected_value = base64::encode(&expected_value);
|
|
let actual_value = checksum.header_value();
|
|
assert_eq!(expected_value, actual_value)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_length_of_sha256_checksum_body() {
|
|
let checksum = SHA_256_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
let expected_size = 66;
|
|
let actual_size = HttpChecksum::size(&*checksum);
|
|
assert_eq!(expected_size, actual_size)
|
|
}
|
|
|
|
#[test]
|
|
fn test_trailer_value_of_sha256_checksum_body() {
|
|
let checksum = SHA_256_NAME.parse::<ChecksumAlgorithm>().unwrap().into_impl();
|
|
let expected_value = Bytes::from_static(&[
|
|
0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41,
|
|
0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
|
|
]);
|
|
let expected_value = base64::encode(&expected_value);
|
|
let actual_value = checksum.header_value();
|
|
assert_eq!(expected_value, actual_value)
|
|
}
|
|
}
|