1use crate::result::{WebSocketError, WebSocketResult};
2use hyper;
3use hyper::header::parsing::from_one_raw_str;
4use hyper::header::{Header, HeaderFormat};
5use std::fmt::{self, Debug};
6use std::str::FromStr;
7
8use websocket_base::header::WebSocketKey as WebSocketKeyLL;
9
10#[derive(PartialEq, Clone, Copy, Default)]
12pub struct WebSocketKey(pub WebSocketKeyLL);
13
14impl Debug for WebSocketKey {
15 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
16 self.0.fmt(f)
17 }
18}
19
20impl FromStr for WebSocketKey {
21 type Err = WebSocketError;
22
23 fn from_str(key: &str) -> WebSocketResult<WebSocketKey> {
24 Ok(WebSocketKey(WebSocketKeyLL::from_str(key)?))
25 }
26}
27
28impl WebSocketKey {
29 pub fn new() -> WebSocketKey {
31 WebSocketKey(WebSocketKeyLL::new())
32 }
33 pub fn serialize(&self) -> String {
35 self.0.serialize()
36 }
37
38 pub fn from_array(a: [u8; 16]) -> WebSocketKey {
40 WebSocketKey(WebSocketKeyLL(a))
41 }
42}
43
44impl Header for WebSocketKey {
45 fn header_name() -> &'static str {
46 "Sec-WebSocket-Key"
47 }
48
49 fn parse_header(raw: &[Vec<u8>]) -> hyper::Result<WebSocketKey> {
50 from_one_raw_str(raw)
51 }
52}
53
54impl HeaderFormat for WebSocketKey {
55 fn fmt_header(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
56 write!(fmt, "{}", self.serialize())
57 }
58}
59
60#[cfg(all(feature = "nightly", test))]
61mod tests {
62 use super::*;
63 use hyper::header::Header;
64 use test;
65
66 #[test]
67 fn test_header_key() {
68 use crate::header::Headers;
69
70 let extensions = WebSocketKey::from_array([65; 16]);
71 let mut headers = Headers::new();
72 headers.set(extensions);
73
74 assert_eq!(
75 &headers.to_string()[..],
76 "Sec-WebSocket-Key: QUFBQUFBQUFBQUFBQUFBQQ==\r\n"
77 );
78 }
79
80 #[test]
81 fn test_header_from_str() {
82 let key = WebSocketKey::from_str("YSByZWFsbCBnb29kIGtleQ==");
83 assert!(key.is_ok()); let key = WebSocketKey::from_str("YSBzaG9ydCBrZXk=");
86 assert!(key.is_err()); let key = WebSocketKey::from_str("YSB2ZXJ5IHZlcnkgbG9uZyBrZXk=");
89 assert!(key.is_err()); }
91
92 #[bench]
93 fn bench_header_key_new(b: &mut test::Bencher) {
94 b.iter(|| {
95 let mut key = WebSocketKey::new();
96 test::black_box(&mut key);
97 });
98 }
99
100 #[bench]
101 fn bench_header_key_parse(b: &mut test::Bencher) {
102 let value = vec![b"QUFBQUFBQUFBQUFBQUFBQQ==".to_vec()];
103 b.iter(|| {
104 let mut key: WebSocketKey = Header::parse_header(&value[..]).unwrap();
105 test::black_box(&mut key);
106 });
107 }
108
109 #[bench]
110 fn bench_header_key_format(b: &mut test::Bencher) {
111 let value = vec![b"QUFBQUFBQUFBQUFBQUFBQQ==".to_vec()];
112 let val: WebSocketKey = Header::parse_header(&value[..]).unwrap();
113 b.iter(|| {
114 format!("{}", val.serialize());
115 });
116 }
117}