codetics_ocpp_ws/
handshake.rs1use crate::{base64, sha1};
7
8const GUID: &str = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
9
10pub fn accept_key(key: &str) -> String {
12 let mut input = key.trim().as_bytes().to_vec();
13 input.extend_from_slice(GUID.as_bytes());
14 base64::encode(&sha1::sha1(&input))
15}
16
17pub fn header_has_token(value: &str, token: &str) -> bool {
19 value
20 .split(',')
21 .any(|t| t.trim().eq_ignore_ascii_case(token))
22}
23
24pub fn valid_client_key(key: &str) -> bool {
26 base64::decode(key).is_some_and(|k| k.len() == 16)
27}
28
29#[cfg(test)]
30mod tests {
31 use super::*;
32
33 #[test]
34 fn rfc_example() {
35 assert_eq!(
37 accept_key("dGhlIHNhbXBsZSBub25jZQ=="),
38 "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
39 );
40 assert_eq!(
41 accept_key("x3JJHMbDL1EzLkh9GBhXDw=="),
42 "HSmrc0sMlYUkAGmm5OPpG2HaGWk="
43 );
44 assert!(valid_client_key("dGhlIHNhbXBsZSBub25jZQ=="));
45 assert!(!valid_client_key("abc"));
46 assert!(header_has_token("keep-alive, Upgrade", "upgrade"));
47 }
48}