feat: add tests

This commit is contained in:
2023-09-29 15:17:02 +08:00
parent d5829504fa
commit ea8a8f872f

View File

@@ -18,10 +18,12 @@ struct Request {
pub product: String,
pub action: String,
pub method: String,
pub endpoint: String,
pub pathname: String,
pub access_key: Option<AccessKey>,
pub user_agent: String,
pub sign_algorithm: SignAlgorithm,
pub query: BTreeMap<String, String>,
pub headers: BTreeMap<String, String>,
pub stream: Option<Vec<u8>>,
}
@@ -29,7 +31,8 @@ struct Request {
fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request) {
let (ymd, date) = get_timestamp();
header.insert_kv(HEADER_HOST, "endpoint"); // TODO
let host = get_host(&request.endpoint);
header.insert_kv(HEADER_HOST, host);
header.insert_kv(HEADER_X_ASC_VERSION, &request.version);
header.insert_kv(HEADER_X_ASC_ACTION, &request.action);
header.insert_kv(HEADER_USER_AGENT, &request.user_agent);
@@ -37,16 +40,14 @@ fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request)
header.insert_kv(HEADER_X_ASC_SIGNATURE_NONCE, get_nonce());
header.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
// TODO BODY ...
// TODO signature ...
let digest_request_payload = digest_request_body(&request.sign_algorithm, &request.stream);
match &request.sign_algorithm {
SignAlgorithm::Sha1 => panic!("SHA1 in V4 is NOT supported!"),
SignAlgorithm::Sha256 => {
header.insert_kv(HEADER_X_ASC_CONTENT_SHA256, "");
header.insert_kv(HEADER_X_ASC_CONTENT_SHA256, &digest_request_payload);
}
SignAlgorithm::Sm3 => {
header.insert_kv(HEADER_X_ASC_CONTENT_SM3, "");
header.insert_kv(HEADER_X_ASC_CONTENT_SM3, &digest_request_payload);
}
}
@@ -92,6 +93,27 @@ fn get_timestamp() -> (String, String) {
("yyyymmdd".into(), "yyyy-mm-dd".into())
}
fn digest_request_body(sign_algorithm: &SignAlgorithm, body: &Option<Vec<u8>>) -> String {
match body {
None => sign_algorithm.digest(&vec![]),
Some(body) => sign_algorithm.digest(body),
}
}
fn get_host(endpoint: &str) -> String {
let lower_endpoint = endpoint.to_ascii_lowercase();
let skip_chars = if lower_endpoint.starts_with("http://") {
7
} else if lower_endpoint.starts_with("https://") {
8
} else if lower_endpoint.starts_with("//") {
2
} else {
0
};
lower_endpoint.chars().skip(skip_chars).take_while(|c| *c != '/').collect()
}
fn get_nonce() -> String {
let seq = SEQ.fetch_add(1, Ordering::Relaxed);
let now = SystemTime::now();
@@ -227,6 +249,31 @@ fn test_get_nonce() {
assert!(nonce.starts_with("nonce-"));
}
#[test]
fn test_digest_request_body() {
assert_eq!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
digest_request_body(&SignAlgorithm::Sha256, &None).as_str());
assert_eq!("ae6d8a1c07f438667618879eae74ffab84c236ea5d8ca52d5ca0523cc35e8bb9",
digest_request_body(&SignAlgorithm::Sha256, &Some("Test Body".as_bytes().to_vec())).as_str());
assert_eq!("1ab21d8355cfa17f8e61194831e81a8f22bec8c728fefb747ed035eb5082aa2b",
digest_request_body(&SignAlgorithm::Sm3, &None).as_str());
assert_eq!("487b3b171a56ba378f0bfd6d6e430774728aa23c13121eba18c54cf39feac0da",
digest_request_body(&SignAlgorithm::Sm3, &Some("Test Body".as_bytes().to_vec())).as_str());
}
#[test]
fn test_get_host() {
assert_eq!("example.com", get_host("http://example.com").as_str());
assert_eq!("example.com", get_host("http://example.com/").as_str());
assert_eq!("example.com", get_host("http://example.com/path").as_str());
assert_eq!("example.com", get_host("https://example.com/path").as_str());
assert_eq!("example.com", get_host("HttPS://EXAMPLE.com/path").as_str());
assert_eq!("example.com", get_host("//EXAMPLE.com/path").as_str());
assert_eq!("example.com", get_host("EXAMPLE.com/path").as_str());
assert_eq!("example.com:8000", get_host("EXAMPLE.com:8000/path").as_str());
assert_eq!("example.com:8000", get_host("hTTPS://EXAMPLE.com:8000/path").as_str());
}
#[test]
fn test_get_signing_key_sha256() {
let signing_key = get_signing_key(