feat: updates
This commit is contained in:
@@ -13,5 +13,6 @@ hmac-sm3 = "0.1.0"
|
||||
rand = "0.8.5"
|
||||
sha1 = "0.10.5"
|
||||
sha256 = "1.4.0"
|
||||
simpledateformat = "0.1.4"
|
||||
sm3 = "0.4.2"
|
||||
zeroize = "1.6.0"
|
||||
|
||||
2
src/lib.rs
Normal file
2
src/lib.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
pub mod util;
|
||||
pub mod v4;
|
||||
28
src/main.rs
28
src/main.rs
@@ -1,6 +1,28 @@
|
||||
mod util;
|
||||
mod v4;
|
||||
use alibabacloud_openapi_signature::util::sign_algorithm::SignAlgorithm;
|
||||
use alibabacloud_openapi_signature::v4::access_key::AccessKey;
|
||||
use alibabacloud_openapi_signature::v4::aliyun_util::{add_common_headers, Request};
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
let mut request = Request {
|
||||
version: "2012-12-31".to_string(),
|
||||
region: Some("cn-hangzhou".to_string()),
|
||||
product: "test".to_string(),
|
||||
action: "DoAction".to_string(),
|
||||
method: "POST".to_string(),
|
||||
endpoint: "ecs.cn-hangzhou.aliyuncs.com".to_string(),
|
||||
pathname: "/do-action".to_string(),
|
||||
access_key: Some(AccessKey {
|
||||
access_key_id: "AccessKeyId".to_string(),
|
||||
security_token: None,
|
||||
access_key_secret: "AccessKeySecret".to_string(),
|
||||
}),
|
||||
user_agent: "TetUa/1.0".to_string(),
|
||||
sign_algorithm: SignAlgorithm::Sha256,
|
||||
query: Default::default(),
|
||||
headers: Default::default(),
|
||||
stream: None,
|
||||
};
|
||||
add_common_headers(&mut request);
|
||||
|
||||
println!("{:#?}", request);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
pub(crate) mod common_util;
|
||||
pub(crate) mod map_util;
|
||||
pub(crate) mod sign_algorithm;
|
||||
pub mod sign_algorithm;
|
||||
@@ -5,7 +5,7 @@ const ACS4_HMAC_SHA256: &str = "ACS4-HMAC-SHA256";
|
||||
const ACS4_HMAC_SM3: &str = "ACS4-HMAC-SM3";
|
||||
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum SignAlgorithm {
|
||||
/// SHA1 is used for Signatures before V4
|
||||
Sha1,
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use rand::random;
|
||||
use simpledateformat::fmt;
|
||||
|
||||
use crate::util::common_util::{join_slices, percent_encode};
|
||||
use crate::util::map_util::BTreeMapAddKv;
|
||||
@@ -12,9 +13,10 @@ use crate::v4::constant::{ALIYUN_V4, ALIYUN_V4_REQUEST, CONTENT_TYPE_APPLICATION
|
||||
|
||||
const SEQ: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
struct Request {
|
||||
#[derive(Debug)]
|
||||
pub struct Request {
|
||||
pub version: String,
|
||||
pub region: String,
|
||||
pub region: Option<String>,
|
||||
pub product: String,
|
||||
pub action: String,
|
||||
pub method: String,
|
||||
@@ -28,42 +30,48 @@ struct Request {
|
||||
pub stream: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request) {
|
||||
pub fn add_common_headers(request: &mut Request) {
|
||||
let (ymd, date) = get_timestamp();
|
||||
|
||||
let headers = &mut request.headers;
|
||||
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);
|
||||
header.insert_kv(HEADER_X_ASC_DATE, date);
|
||||
header.insert_kv(HEADER_X_ASC_SIGNATURE_NONCE, get_nonce());
|
||||
header.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
||||
headers.insert_kv(HEADER_HOST, host);
|
||||
headers.insert_kv(HEADER_X_ASC_VERSION, &request.version);
|
||||
headers.insert_kv(HEADER_X_ASC_ACTION, &request.action);
|
||||
headers.insert_kv(HEADER_USER_AGENT, &request.user_agent);
|
||||
headers.insert_kv(HEADER_X_ASC_DATE, date);
|
||||
headers.insert_kv(HEADER_X_ASC_SIGNATURE_NONCE, get_nonce());
|
||||
headers.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
||||
|
||||
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, &digest_request_payload);
|
||||
headers.insert_kv(HEADER_X_ASC_CONTENT_SHA256, &digest_request_payload);
|
||||
}
|
||||
SignAlgorithm::Sm3 => {
|
||||
header.insert_kv(HEADER_X_ASC_CONTENT_SM3, &digest_request_payload);
|
||||
headers.insert_kv(HEADER_X_ASC_CONTENT_SM3, &digest_request_payload);
|
||||
}
|
||||
}
|
||||
|
||||
let query = BTreeMap::new();
|
||||
|
||||
if let Some(access_key) = &request.access_key {
|
||||
headers.insert_kv(HEADER_X_ASC_ACCESS_KEY_ID, &access_key.access_key_id);
|
||||
if let Some(security_token) = &access_key.security_token {
|
||||
header.insert_kv(HEADER_X_ASC_ACCESS_KEY_ID, &access_key.access_key_id);
|
||||
header.insert_kv(HEADER_X_ASC_SECURITY_TOKEN, security_token);
|
||||
headers.insert_kv(HEADER_X_ASC_SECURITY_TOKEN, security_token);
|
||||
}
|
||||
|
||||
let region = match &request.region {
|
||||
None => get_region(&request.product, &request.endpoint),
|
||||
Some(region) => region.to_string(),
|
||||
};
|
||||
|
||||
let signing_key = get_signing_key(
|
||||
&request.sign_algorithm,
|
||||
&access_key.access_key_secret,
|
||||
&ymd,
|
||||
&request.region,
|
||||
®ion,
|
||||
&request.product,
|
||||
);
|
||||
let derived_access_key = DerivedAccessKey {
|
||||
@@ -74,22 +82,25 @@ fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request)
|
||||
&request.sign_algorithm,
|
||||
&derived_access_key,
|
||||
&ymd,
|
||||
&request.region,
|
||||
®ion,
|
||||
&request.product,
|
||||
&request.pathname,
|
||||
&request.method,
|
||||
&query,
|
||||
header,
|
||||
headers,
|
||||
&digest_request_payload,
|
||||
);
|
||||
header.insert_kv(HEADER_AUTHORIZATION, authorization);
|
||||
headers.insert_kv(HEADER_AUTHORIZATION, authorization);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn get_timestamp() -> (String, String) {
|
||||
// TODO ...
|
||||
("yyyymmdd".into(), "yyyy-mm-dd".into())
|
||||
let ymd_format = "yyyyMMdd";
|
||||
let ymd_hms_format = "yyyy-MM-dd'T'HH:mm:ss'Z'";
|
||||
let now = simpledateformat::get_utc_now();
|
||||
let ymd = fmt(ymd_format).unwrap().format(&now);
|
||||
let ymd_hms = fmt(ymd_hms_format).unwrap().format(&now);
|
||||
(ymd, ymd_hms)
|
||||
}
|
||||
|
||||
fn digest_request_body(sign_algorithm: &SignAlgorithm, body: &Option<Vec<u8>>) -> String {
|
||||
@@ -248,6 +259,16 @@ fn test_get_nonce() {
|
||||
assert!(nonce.starts_with("nonce-"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_timestamp() {
|
||||
let (ymd, ymd_hms) = get_timestamp();
|
||||
let ymd_hms_take: String = ymd_hms.chars()
|
||||
.filter(|c| *c != '-')
|
||||
.take_while(|c| *c != 'T')
|
||||
.collect();
|
||||
assert_eq!(ymd, ymd_hms_take);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_digest_request_body() {
|
||||
assert_eq!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
mod constant;
|
||||
mod access_key;
|
||||
mod aliyun_util;
|
||||
pub mod constant;
|
||||
pub mod access_key;
|
||||
pub mod aliyun_util;
|
||||
|
||||
Reference in New Issue
Block a user