use sha1::Sha1; use hmac::{Hmac, Mac}; use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD}; use reqwest::multipart; type HmacSha1 = Hmac; fn generate_token(ak: &str, sk: &str, bucket: &str, key: &str, scope_key: bool) -> String { let deadline = chrono::Utc::now().timestamp() + 3600; let scope = if scope_key { format!("{}:{}", bucket, key) } else { bucket.to_string() }; let policy = serde_json::json!({ "scope": scope, "deadline": deadline }); let policy_str = policy.to_string(); let encoded_policy = URL_SAFE_NO_PAD.encode(policy_str.as_bytes()); let mut mac = HmacSha1::new_from_slice(sk.as_bytes()).unwrap(); mac.update(encoded_policy.as_bytes()); let signature = mac.finalize().into_bytes(); let encoded_signature = URL_SAFE_NO_PAD.encode(&signature); format!("{}:{}:{}", ak, encoded_signature, encoded_policy) } #[tokio::main] async fn main() -> Result<(), Box> { let ak = "vf63aPF-QIFbyzULtHaSx9JgiVSS3zRuy0zmBACE".to_string(); let sk = "JlQvHevHSAgilNYaH0UxQoX68rb4m9VflpaXtYL1".to_string(); let bucket = "fmqi-img".to_string(); let domain = "http://qnimg.asfmq.cn".to_string(); let client = reqwest::Client::new(); let dummy_data = b"hello world qiniu test".to_vec(); let filename = "test_hello.txt"; let key = "astroresearch/test_hello.txt"; println!("Testing with scoped key token (bucket:key)..."); let token1 = generate_token(&ak, &sk, &bucket, key, true); let form1 = multipart::Form::new() .text("token", token1) .text("key", key) .part("file", multipart::Part::bytes(dummy_data.clone()).file_name(filename)); let res1 = client.post("https://up-z1.qiniup.com").multipart(form1).send().await?; println!("Status (scoped key): {}", res1.status()); println!("Response: {}", res1.text().await?); println!("\nTesting with bucket-only scoped token..."); let token2 = generate_token(&ak, &sk, &bucket, key, false); let form2 = multipart::Form::new() .text("token", token2) .text("key", key) .part("file", multipart::Part::bytes(dummy_data).file_name(filename)); let res2 = client.post("https://up-z1.qiniup.com").multipart(form2).send().await?; println!("Status (bucket-only): {}", res2.status()); println!("Response: {}", res2.text().await?); Ok(()) }