1use std::{
2 collections::HashMap,
3 time::{SystemTime, UNIX_EPOCH},
4};
5
6use hyper::Uri;
7use serde::Deserialize;
8
9use crate::{FORWARD_LOGGER_DOMAIN, debug_log};
10
11#[derive(Debug, Deserialize)]
12pub struct SignParams {
13 #[serde(default)]
14 pub(crate) sign: String,
15
16 #[serde(default)]
17 pub(crate) device_id: String,
18
19 #[serde(default, rename = "session_id")]
20 pub(crate) playback_session_id: String,
21}
22
23impl Default for SignParams {
24 fn default() -> Self {
25 Self {
26 sign: "".into(),
27 device_id: "".into(),
28 playback_session_id: "".into(),
29 }
30 }
31}
32
33#[derive(Clone, Debug, Default)]
34pub struct Sign {
35 pub uri: Option<Uri>,
36 pub expired_at: Option<u64>,
37}
38
39impl Sign {
40 pub fn new(uri: Option<Uri>, expired_at: Option<u64>) -> Self {
41 Self { uri, expired_at }
42 }
43
44 pub fn from_map(map: &HashMap<String, String>) -> Self {
45 debug_log!(FORWARD_LOGGER_DOMAIN, "Map to sign: {:?}", map);
46 let mut sign = Sign::default();
47
48 if let Some(uri_str) = map.get("uri") {
49 sign.uri = uri_str.parse::<Uri>().ok();
50 }
51
52 if let Some(expired_at_str) = map.get("expired_at") {
53 sign.expired_at = expired_at_str.parse::<u64>().ok();
54 }
55
56 sign
57 }
58
59 pub fn to_map(&self) -> HashMap<String, String> {
60 debug_log!(
61 FORWARD_LOGGER_DOMAIN,
62 "Sign to map by uri: {:?} expired_at: {:?}",
63 self.uri,
64 self.expired_at
65 );
66 let mut map = HashMap::new();
67
68 if let Some(uri) = &self.uri {
69 map.insert("uri".to_string(), uri.to_string());
70 }
71
72 if let Some(expired_at) = self.expired_at {
73 map.insert("expired_at".to_string(), expired_at.to_string());
74 }
75
76 map
77 }
78
79 pub fn is_valid(&self) -> bool {
80 let Some(expired_at) = self.expired_at else {
81 return false;
82 };
83
84 let now = SystemTime::now()
85 .duration_since(UNIX_EPOCH)
86 .map(|d| d.as_secs())
87 .unwrap_or(0);
88
89 if now >= expired_at + 300 {
90 return false;
91 }
92
93 let Some(uri) = &self.uri else {
94 return false;
95 };
96
97 !uri.to_string().is_empty()
98 }
99}