http_type/websocket_frame/
impl.rs1use crate::*;
2
3impl WebSocketFrame {
4 #[inline]
13 pub fn decode_websocket_frame_with_length(data: &[u8]) -> WebsocketFrameWithLengthOption {
14 if data.len() < 2 {
15 return None;
16 }
17 let mut index: usize = 0;
18 let fin: bool = (data[index] & 0b1000_0000) != 0;
19 let opcode: u8 = data[index] & 0b0000_1111;
20 index += 1;
21 let mask: bool = (data[index] & 0b1000_0000) != 0;
22 let mut payload_len: usize = (data[index] & 0b0111_1111) as usize;
23 index += 1;
24 if payload_len == 126 {
25 if data.len() < index + 2 {
26 return None;
27 }
28 payload_len = u16::from_be_bytes(data[index..index + 2].try_into().ok()?) as usize;
29 index += 2;
30 } else if payload_len == 127 {
31 if data.len() < index + 8 {
32 return None;
33 }
34 payload_len = u64::from_be_bytes(data[index..index + 8].try_into().ok()?) as usize;
35 index += 8;
36 }
37 let mask_key: Option<[u8; 4]> = if mask {
38 if data.len() < index + 4 {
39 return None;
40 }
41 let key: [u8; 4] = data[index..index + 4].try_into().ok()?;
42 index += 4;
43 Some(key)
44 } else {
45 None
46 };
47 if data.len() < index + payload_len {
48 return None;
49 }
50 let mut payload: Vec<u8> = data[index..index + payload_len].to_vec();
51 if let Some(mask_key) = mask_key {
52 for (i, byte) in payload.iter_mut().enumerate() {
53 *byte ^= mask_key[i % 4];
54 }
55 }
56 index += payload_len;
57 let frame: WebSocketFrame = WebSocketFrame {
58 fin,
59 opcode,
60 mask,
61 payload_data: payload,
62 };
63 Some((frame, index))
64 }
65
66 #[inline]
71 pub fn create_response_frame_list(body: &ResponseBody) -> Vec<ResponseBody> {
72 let total_len: usize = body.len();
73 let mut offset: usize = 0;
74 let mut frames_list: Vec<ResponseBody> = Vec::new();
75 let mut is_first_frame: bool = true;
76 let is_valid_utf8: bool = std::str::from_utf8(body).is_ok();
77 let base_opcode: u8 = if is_valid_utf8 { 0x01 } else { 0x02 };
78 while offset < total_len {
79 let remaining: usize = total_len - offset;
80 let mut frame_size: usize = remaining.min(MAX_FRAME_SIZE);
81 if is_valid_utf8 && frame_size < remaining {
82 while frame_size > 0 && (body[offset + frame_size] & 0xC0) == 0x80 {
83 frame_size -= 1;
84 }
85 if frame_size == 0 {
86 frame_size = remaining.min(MAX_FRAME_SIZE);
87 }
88 }
89 let mut frame: ResponseBody = Vec::with_capacity(frame_size + 10);
90 let opcode: u8 = if is_first_frame { base_opcode } else { 0x00 };
91 let fin_bit: u8 = if remaining > frame_size { 0x00 } else { 0x80 };
92 frame.push(fin_bit | opcode);
93 if frame_size < 126 {
94 frame.push(frame_size as u8);
95 } else if frame_size <= MAX_FRAME_SIZE {
96 frame.push(126);
97 frame.extend_from_slice(&(frame_size as u16).to_be_bytes());
98 } else {
99 frame.push(127);
100 frame.extend_from_slice(&(frame_size as u64).to_be_bytes());
101 }
102 frame.extend_from_slice(&body[offset..offset + frame_size]);
103 frames_list.push(frame);
104 offset += frame_size;
105 is_first_frame = false;
106 }
107 frames_list
108 }
109
110 #[inline]
115 pub fn sha1(data: &[u8]) -> [u8; 20] {
116 let mut hash_state: [u32; 5] = HASH_STATE;
117 let mut padded_data: Vec<u8> = Vec::from(data);
118 let original_length_bits: u64 = (padded_data.len() * 8) as u64;
119 padded_data.push(0x80);
120 while (padded_data.len() + 8) % 64 != 0 {
121 padded_data.push(0);
122 }
123 padded_data.extend_from_slice(&original_length_bits.to_be_bytes());
124 for block in padded_data.chunks_exact(64) {
125 let mut message_schedule: [u32; 80] = [0u32; 80];
126 for (i, block_chunk) in block.chunks_exact(4).enumerate().take(16) {
127 message_schedule[i] = u32::from_be_bytes([
128 block_chunk[0],
129 block_chunk[1],
130 block_chunk[2],
131 block_chunk[3],
132 ]);
133 }
134 for i in 16..80 {
135 message_schedule[i] = (message_schedule[i - 3]
136 ^ message_schedule[i - 8]
137 ^ message_schedule[i - 14]
138 ^ message_schedule[i - 16])
139 .rotate_left(1);
140 }
141 let [mut a, mut b, mut c, mut d, mut e] = hash_state;
142 for (i, &word) in message_schedule.iter().enumerate() {
143 let (f, k) = match i {
144 0..=19 => ((b & c) | (!b & d), 0x5A827999),
145 20..=39 => (b ^ c ^ d, 0x6ED9EBA1),
146 40..=59 => ((b & c) | (b & d) | (c & d), 0x8F1BBCDC),
147 _ => (b ^ c ^ d, 0xCA62C1D6),
148 };
149 let temp: u32 = a
150 .rotate_left(5)
151 .wrapping_add(f)
152 .wrapping_add(e)
153 .wrapping_add(k)
154 .wrapping_add(word);
155 e = d;
156 d = c;
157 c = b.rotate_left(30);
158 b = a;
159 a = temp;
160 }
161 hash_state[0] = hash_state[0].wrapping_add(a);
162 hash_state[1] = hash_state[1].wrapping_add(b);
163 hash_state[2] = hash_state[2].wrapping_add(c);
164 hash_state[3] = hash_state[3].wrapping_add(d);
165 hash_state[4] = hash_state[4].wrapping_add(e);
166 }
167 let mut result: [u8; 20] = [0u8; 20];
168 for (i, &val) in hash_state.iter().enumerate() {
169 result[i * 4..(i + 1) * 4].copy_from_slice(&val.to_be_bytes());
170 }
171 result
172 }
173
174 #[inline]
179 pub fn generate_accept_key(key: &str) -> String {
180 let mut data: [u8; 60] = [0u8; 60];
181 data[..24].copy_from_slice(&key.as_bytes()[..24.min(key.len())]);
182 data[24..].copy_from_slice(GUID);
183 let hash: [u8; 20] = Self::sha1(&data);
184 Self::base64_encode(&hash)
185 }
186
187 #[inline]
192 pub fn base64_encode(data: &[u8]) -> String {
193 let mut encoded_data: Vec<u8> = Vec::with_capacity((data.len() + 2) / 3 * 4);
194 for chunk in data.chunks(3) {
195 let mut buffer: [u8; 3] = [0u8; 3];
196 buffer[..chunk.len()].copy_from_slice(chunk);
197 let indices: [u8; 4] = [
198 buffer[0] >> 2,
199 ((buffer[0] & 0b11) << 4) | (buffer[1] >> 4),
200 ((buffer[1] & 0b1111) << 2) | (buffer[2] >> 6),
201 buffer[2] & 0b111111,
202 ];
203 for &idx in &indices[..chunk.len() + 1] {
204 encoded_data.push(BASE64_CHARSET_TABLE[idx as usize]);
205 }
206 while encoded_data.len() % 4 != 0 {
207 encoded_data.push(EQUAL_BYTES[0]);
208 }
209 }
210 String::from_utf8(encoded_data).unwrap()
211 }
212}