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