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 pub fn create_response_frame_list(body: &ResponseBody) -> Vec<ResponseBody> {
70 let total_len: usize = body.len();
71 let mut offset: usize = 0;
72 let mut frames_list: Vec<ResponseBody> = Vec::new();
73 let mut is_first_frame: bool = true;
74 let is_valid_utf8: bool = std::str::from_utf8(body).is_ok();
75 let base_opcode: u8 = if is_valid_utf8 { 0x01 } else { 0x02 };
76 while offset < total_len {
77 let remaining: usize = total_len - offset;
78 let mut frame_size: usize = remaining.min(MAX_FRAME_SIZE);
79 if is_valid_utf8 && frame_size < remaining {
80 while frame_size > 0 && (body[offset + frame_size] & 0xC0) == 0x80 {
81 frame_size -= 1;
82 }
83 if frame_size == 0 {
84 frame_size = remaining.min(MAX_FRAME_SIZE);
85 }
86 }
87 let mut frame: ResponseBody = Vec::with_capacity(frame_size + 10);
88 let opcode: u8 = if is_first_frame { base_opcode } else { 0x00 };
89 let fin_bit: u8 = if remaining > frame_size { 0x00 } else { 0x80 };
90 frame.push(fin_bit | opcode);
91 if frame_size < 126 {
92 frame.push(frame_size as u8);
93 } else if frame_size <= MAX_FRAME_SIZE {
94 frame.push(126);
95 frame.extend_from_slice(&(frame_size as u16).to_be_bytes());
96 } else {
97 frame.push(127);
98 frame.extend_from_slice(&(frame_size as u64).to_be_bytes());
99 }
100 frame.extend_from_slice(&body[offset..offset + frame_size]);
101 frames_list.push(frame);
102 offset += frame_size;
103 is_first_frame = false;
104 }
105 frames_list
106 }
107
108 pub fn sha1(data: &[u8]) -> [u8; 20] {
113 let mut hash_state: [u32; 5] = HASH_STATE;
114 let mut padded_data: Vec<u8> = Vec::from(data);
115 let original_length_bits: u64 = (padded_data.len() * 8) as u64;
116 padded_data.push(0x80);
117 while (padded_data.len() + 8) % 64 != 0 {
118 padded_data.push(0);
119 }
120 padded_data.extend_from_slice(&original_length_bits.to_be_bytes());
121 for block in padded_data.chunks_exact(64) {
122 let mut message_schedule: [u32; 80] = [0u32; 80];
123 for (i, block_chunk) in block.chunks_exact(4).enumerate().take(16) {
124 message_schedule[i] = u32::from_be_bytes([
125 block_chunk[0],
126 block_chunk[1],
127 block_chunk[2],
128 block_chunk[3],
129 ]);
130 }
131 for i in 16..80 {
132 message_schedule[i] = (message_schedule[i - 3]
133 ^ message_schedule[i - 8]
134 ^ message_schedule[i - 14]
135 ^ message_schedule[i - 16])
136 .rotate_left(1);
137 }
138 let [mut a, mut b, mut c, mut d, mut e] = hash_state;
139 for (i, &word) in message_schedule.iter().enumerate() {
140 let (f, k) = match i {
141 0..=19 => ((b & c) | (!b & d), 0x5A827999),
142 20..=39 => (b ^ c ^ d, 0x6ED9EBA1),
143 40..=59 => ((b & c) | (b & d) | (c & d), 0x8F1BBCDC),
144 _ => (b ^ c ^ d, 0xCA62C1D6),
145 };
146 let temp: u32 = a
147 .rotate_left(5)
148 .wrapping_add(f)
149 .wrapping_add(e)
150 .wrapping_add(k)
151 .wrapping_add(word);
152 e = d;
153 d = c;
154 c = b.rotate_left(30);
155 b = a;
156 a = temp;
157 }
158 hash_state[0] = hash_state[0].wrapping_add(a);
159 hash_state[1] = hash_state[1].wrapping_add(b);
160 hash_state[2] = hash_state[2].wrapping_add(c);
161 hash_state[3] = hash_state[3].wrapping_add(d);
162 hash_state[4] = hash_state[4].wrapping_add(e);
163 }
164 let mut result: [u8; 20] = [0u8; 20];
165 for (i, &val) in hash_state.iter().enumerate() {
166 result[i * 4..(i + 1) * 4].copy_from_slice(&val.to_be_bytes());
167 }
168 result
169 }
170
171 pub fn generate_accept_key(key: &str) -> String {
176 let mut data: [u8; 60] = [0u8; 60];
177 data[..24].copy_from_slice(&key.as_bytes()[..24.min(key.len())]);
178 data[24..].copy_from_slice(GUID);
179 let hash: [u8; 20] = Self::sha1(&data);
180 Self::base64_encode(&hash)
181 }
182
183 pub fn base64_encode(data: &[u8]) -> String {
188 let mut encoded_data: Vec<u8> = Vec::with_capacity((data.len() + 2) / 3 * 4);
189 for chunk in data.chunks(3) {
190 let mut buffer: [u8; 3] = [0u8; 3];
191 buffer[..chunk.len()].copy_from_slice(chunk);
192 let indices: [u8; 4] = [
193 buffer[0] >> 2,
194 ((buffer[0] & 0b11) << 4) | (buffer[1] >> 4),
195 ((buffer[1] & 0b1111) << 2) | (buffer[2] >> 6),
196 buffer[2] & 0b111111,
197 ];
198 for &idx in &indices[..chunk.len() + 1] {
199 encoded_data.push(BASE64_CHARSET_TABLE[idx as usize]);
200 }
201 while encoded_data.len() % 4 != 0 {
202 encoded_data.push(EQUAL_BYTES[0]);
203 }
204 }
205 String::from_utf8(encoded_data).unwrap()
206 }
207}