websocket/header/
key.rs

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/// Represents a Sec-WebSocket-Key header.
11#[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	/// Generate a new, random WebSocketKey
30	pub fn new() -> WebSocketKey {
31		WebSocketKey(WebSocketKeyLL::new())
32	}
33	/// Return the Base64 encoding of this WebSocketKey
34	pub fn serialize(&self) -> String {
35		self.0.serialize()
36	}
37
38	/// Create WebSocketKey by explicitly specifying the key
39	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()); // 16 bytes
84
85		let key = WebSocketKey::from_str("YSBzaG9ydCBrZXk=");
86		assert!(key.is_err()); // < 16 bytes
87
88		let key = WebSocketKey::from_str("YSB2ZXJ5IHZlcnkgbG9uZyBrZXk=");
89		assert!(key.is_err()); // > 16 bytes
90	}
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}