feat: add tests
This commit is contained in:
@@ -18,10 +18,12 @@ struct Request {
|
|||||||
pub product: String,
|
pub product: String,
|
||||||
pub action: String,
|
pub action: String,
|
||||||
pub method: String,
|
pub method: String,
|
||||||
|
pub endpoint: String,
|
||||||
pub pathname: String,
|
pub pathname: String,
|
||||||
pub access_key: Option<AccessKey>,
|
pub access_key: Option<AccessKey>,
|
||||||
pub user_agent: String,
|
pub user_agent: String,
|
||||||
pub sign_algorithm: SignAlgorithm,
|
pub sign_algorithm: SignAlgorithm,
|
||||||
|
pub query: BTreeMap<String, String>,
|
||||||
pub headers: BTreeMap<String, String>,
|
pub headers: BTreeMap<String, String>,
|
||||||
pub stream: Option<Vec<u8>>,
|
pub stream: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
@@ -29,7 +31,8 @@ struct Request {
|
|||||||
fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request) {
|
fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request) {
|
||||||
let (ymd, date) = get_timestamp();
|
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_VERSION, &request.version);
|
||||||
header.insert_kv(HEADER_X_ASC_ACTION, &request.action);
|
header.insert_kv(HEADER_X_ASC_ACTION, &request.action);
|
||||||
header.insert_kv(HEADER_USER_AGENT, &request.user_agent);
|
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_X_ASC_SIGNATURE_NONCE, get_nonce());
|
||||||
header.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
header.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
||||||
|
|
||||||
// TODO BODY ...
|
let digest_request_payload = digest_request_body(&request.sign_algorithm, &request.stream);
|
||||||
|
|
||||||
// TODO signature ...
|
|
||||||
match &request.sign_algorithm {
|
match &request.sign_algorithm {
|
||||||
SignAlgorithm::Sha1 => panic!("SHA1 in V4 is NOT supported!"),
|
SignAlgorithm::Sha1 => panic!("SHA1 in V4 is NOT supported!"),
|
||||||
SignAlgorithm::Sha256 => {
|
SignAlgorithm::Sha256 => {
|
||||||
header.insert_kv(HEADER_X_ASC_CONTENT_SHA256, "");
|
header.insert_kv(HEADER_X_ASC_CONTENT_SHA256, &digest_request_payload);
|
||||||
}
|
}
|
||||||
SignAlgorithm::Sm3 => {
|
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())
|
("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 {
|
fn get_nonce() -> String {
|
||||||
let seq = SEQ.fetch_add(1, Ordering::Relaxed);
|
let seq = SEQ.fetch_add(1, Ordering::Relaxed);
|
||||||
let now = SystemTime::now();
|
let now = SystemTime::now();
|
||||||
@@ -227,6 +249,31 @@ fn test_get_nonce() {
|
|||||||
assert!(nonce.starts_with("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]
|
#[test]
|
||||||
fn test_get_signing_key_sha256() {
|
fn test_get_signing_key_sha256() {
|
||||||
let signing_key = get_signing_key(
|
let signing_key = get_signing_key(
|
||||||
|
|||||||
Reference in New Issue
Block a user