feat: updates
This commit is contained in:
@@ -13,5 +13,6 @@ hmac-sm3 = "0.1.0"
|
|||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
sha1 = "0.10.5"
|
sha1 = "0.10.5"
|
||||||
sha256 = "1.4.0"
|
sha256 = "1.4.0"
|
||||||
|
simpledateformat = "0.1.4"
|
||||||
sm3 = "0.4.2"
|
sm3 = "0.4.2"
|
||||||
zeroize = "1.6.0"
|
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;
|
use alibabacloud_openapi_signature::util::sign_algorithm::SignAlgorithm;
|
||||||
mod v4;
|
use alibabacloud_openapi_signature::v4::access_key::AccessKey;
|
||||||
|
use alibabacloud_openapi_signature::v4::aliyun_util::{add_common_headers, Request};
|
||||||
|
|
||||||
fn main() {
|
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 common_util;
|
||||||
pub(crate) mod map_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";
|
const ACS4_HMAC_SM3: &str = "ACS4-HMAC-SM3";
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum SignAlgorithm {
|
pub enum SignAlgorithm {
|
||||||
/// SHA1 is used for Signatures before V4
|
/// SHA1 is used for Signatures before V4
|
||||||
Sha1,
|
Sha1,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
|||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
use simpledateformat::fmt;
|
||||||
|
|
||||||
use crate::util::common_util::{join_slices, percent_encode};
|
use crate::util::common_util::{join_slices, percent_encode};
|
||||||
use crate::util::map_util::BTreeMapAddKv;
|
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);
|
const SEQ: AtomicU64 = AtomicU64::new(0);
|
||||||
|
|
||||||
struct Request {
|
#[derive(Debug)]
|
||||||
|
pub struct Request {
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub region: String,
|
pub region: Option<String>,
|
||||||
pub product: String,
|
pub product: String,
|
||||||
pub action: String,
|
pub action: String,
|
||||||
pub method: String,
|
pub method: String,
|
||||||
@@ -28,42 +30,48 @@ struct Request {
|
|||||||
pub stream: Option<Vec<u8>>,
|
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 (ymd, date) = get_timestamp();
|
||||||
|
|
||||||
|
let headers = &mut request.headers;
|
||||||
let host = get_host(&request.endpoint);
|
let host = get_host(&request.endpoint);
|
||||||
header.insert_kv(HEADER_HOST, host);
|
headers.insert_kv(HEADER_HOST, host);
|
||||||
header.insert_kv(HEADER_X_ASC_VERSION, &request.version);
|
headers.insert_kv(HEADER_X_ASC_VERSION, &request.version);
|
||||||
header.insert_kv(HEADER_X_ASC_ACTION, &request.action);
|
headers.insert_kv(HEADER_X_ASC_ACTION, &request.action);
|
||||||
header.insert_kv(HEADER_USER_AGENT, &request.user_agent);
|
headers.insert_kv(HEADER_USER_AGENT, &request.user_agent);
|
||||||
header.insert_kv(HEADER_X_ASC_DATE, date);
|
headers.insert_kv(HEADER_X_ASC_DATE, date);
|
||||||
header.insert_kv(HEADER_X_ASC_SIGNATURE_NONCE, get_nonce());
|
headers.insert_kv(HEADER_X_ASC_SIGNATURE_NONCE, get_nonce());
|
||||||
header.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
headers.insert_kv(HEADER_ACCEPT, CONTENT_TYPE_APPLICATION_JSON);
|
||||||
|
|
||||||
let digest_request_payload = digest_request_body(&request.sign_algorithm, &request.stream);
|
let digest_request_payload = digest_request_body(&request.sign_algorithm, &request.stream);
|
||||||
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, &digest_request_payload);
|
headers.insert_kv(HEADER_X_ASC_CONTENT_SHA256, &digest_request_payload);
|
||||||
}
|
}
|
||||||
SignAlgorithm::Sm3 => {
|
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();
|
let query = BTreeMap::new();
|
||||||
|
|
||||||
if let Some(access_key) = &request.access_key {
|
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 {
|
if let Some(security_token) = &access_key.security_token {
|
||||||
header.insert_kv(HEADER_X_ASC_ACCESS_KEY_ID, &access_key.access_key_id);
|
headers.insert_kv(HEADER_X_ASC_SECURITY_TOKEN, security_token);
|
||||||
header.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(
|
let signing_key = get_signing_key(
|
||||||
&request.sign_algorithm,
|
&request.sign_algorithm,
|
||||||
&access_key.access_key_secret,
|
&access_key.access_key_secret,
|
||||||
&ymd,
|
&ymd,
|
||||||
&request.region,
|
®ion,
|
||||||
&request.product,
|
&request.product,
|
||||||
);
|
);
|
||||||
let derived_access_key = DerivedAccessKey {
|
let derived_access_key = DerivedAccessKey {
|
||||||
@@ -74,22 +82,25 @@ fn add_common_headers(header: &mut BTreeMap<String, String>, request: &Request)
|
|||||||
&request.sign_algorithm,
|
&request.sign_algorithm,
|
||||||
&derived_access_key,
|
&derived_access_key,
|
||||||
&ymd,
|
&ymd,
|
||||||
&request.region,
|
®ion,
|
||||||
&request.product,
|
&request.product,
|
||||||
&request.pathname,
|
&request.pathname,
|
||||||
&request.method,
|
&request.method,
|
||||||
&query,
|
&query,
|
||||||
header,
|
headers,
|
||||||
&digest_request_payload,
|
&digest_request_payload,
|
||||||
);
|
);
|
||||||
header.insert_kv(HEADER_AUTHORIZATION, authorization);
|
headers.insert_kv(HEADER_AUTHORIZATION, authorization);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn get_timestamp() -> (String, String) {
|
fn get_timestamp() -> (String, String) {
|
||||||
// TODO ...
|
let ymd_format = "yyyyMMdd";
|
||||||
("yyyymmdd".into(), "yyyy-mm-dd".into())
|
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 {
|
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-"));
|
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]
|
#[test]
|
||||||
fn test_digest_request_body() {
|
fn test_digest_request_body() {
|
||||||
assert_eq!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
assert_eq!("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
mod constant;
|
pub mod constant;
|
||||||
mod access_key;
|
pub mod access_key;
|
||||||
mod aliyun_util;
|
pub mod aliyun_util;
|
||||||
|
|||||||
Reference in New Issue
Block a user