signature.rs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. use std::process;
  2. use base64; // https://crates.io/crates/base64
  3. use hex::{self, FromHexError}; // https://crates.io/crates/hex
  4. use hmac::{Hmac, Mac}; // https://crates.io/crates/hmac
  5. use sha2::Sha256; // https://crates.io/crates/sha2
  6. type HmacSha256 = Hmac<Sha256>;
  7. const KEY: &'static str = "943b421c9eb07c830af81030552c86009268de4e532ba2ee2eab8247c6da0881";
  8. const SALT: &'static str = "520f986b998545b4785e0defbc4f3c1203f22de2374a3d53cb7a7fe9fea309c5";
  9. pub struct Image {
  10. pub src: &'static str,
  11. pub width: usize,
  12. pub height: usize,
  13. pub dpr: u8,
  14. pub ext: &'static str,
  15. }
  16. #[derive(Debug)]
  17. pub enum Error {
  18. InvalidKey(FromHexError),
  19. InvalidSalt(FromHexError),
  20. }
  21. fn main() {
  22. let path = "/rs:fit:300:300/plain/http://img.example.com/pretty/image.jpg";
  23. match sign_path(path) {
  24. Ok(signed_path) => {
  25. println!("{}", signed_path);
  26. process::exit(0);
  27. }
  28. Err(err) => {
  29. eprintln!("{:#?}", err);
  30. process::exit(1);
  31. }
  32. }
  33. }
  34. pub fn sign_path(path: &str) -> Result<String, Error> {
  35. let decoded_key = match hex::decode(KEY) {
  36. Ok(key) => key,
  37. Err(err) => return Err(Error::InvalidKey(err)),
  38. };
  39. let decoded_salt = match hex::decode(SALT) {
  40. Ok(salt) => salt,
  41. Err(err) => return Err(Error::InvalidSalt(err)),
  42. };
  43. let mut hmac = HmacSha256::new_from_slice(&decoded_key).unwrap();
  44. hmac.update(&decoded_salt);
  45. hmac.update(path.as_bytes());
  46. let signature = hmac.finalize().into_bytes();
  47. let signature = base64::encode_config(signature.as_slice(), base64::URL_SAFE_NO_PAD);
  48. let signed_path = format!("/{}{}", signature, path);
  49. Ok(signed_path)
  50. }