flare_core/common/message/
parser.rs1use crate::common::compression::{CompressionAlgorithm, CompressionUtil};
7use crate::common::encryption::{EncryptionAlgorithm, EncryptionUtil};
8use crate::common::error::Result;
9use crate::common::protocol::{Frame, SerializationFormat};
10use crate::common::serializer::SerializationUtil;
11use lazy_static::lazy_static;
12
13pub const MIN_COMPRESSION_PAYLOAD_BYTES: usize = 512;
19
20lazy_static! {
25 pub static ref PRE_NEGOTIATION_PARSER: MessageParser = MessageParser::new(
26 SerializationFormat::Json,
27 CompressionAlgorithm::None,
28 EncryptionAlgorithm::None,
29 );
30}
31
32#[derive(Debug, Clone)]
34pub struct MessageParser {
35 default_format: SerializationFormat,
36 default_compression: CompressionAlgorithm,
37 default_encryption: EncryptionAlgorithm,
38 custom_format_name: Option<String>,
44}
45
46impl MessageParser {
47 pub fn new(
49 format: SerializationFormat,
50 compression: CompressionAlgorithm,
51 encryption: EncryptionAlgorithm,
52 ) -> Self {
53 Self {
54 default_format: format,
55 default_compression: compression,
56 default_encryption: encryption,
57 custom_format_name: None,
58 }
59 }
60
61 pub fn with_custom_format(
82 format_name: &str,
83 compression: CompressionAlgorithm,
84 encryption: EncryptionAlgorithm,
85 ) -> Self {
86 Self {
87 default_format: SerializationFormat::Json, default_compression: compression,
89 default_encryption: encryption,
90 custom_format_name: Some(format_name.to_string()),
91 }
92 }
93
94 pub fn new_with_format_compression(
96 format: SerializationFormat,
97 compression: CompressionAlgorithm,
98 ) -> Self {
99 Self::new(format, compression, EncryptionAlgorithm::None)
100 }
101
102 pub fn protobuf() -> Self {
104 Self::new(
105 SerializationFormat::Protobuf,
106 CompressionAlgorithm::None,
107 EncryptionAlgorithm::None,
108 )
109 }
110
111 pub fn json() -> Self {
113 Self::new(
114 SerializationFormat::Json,
115 CompressionAlgorithm::None,
116 EncryptionAlgorithm::None,
117 )
118 }
119
120 pub fn default_format(&self) -> SerializationFormat {
122 self.default_format
123 }
124
125 pub fn default_compression(&self) -> CompressionAlgorithm {
127 self.default_compression.clone()
128 }
129
130 pub fn default_encryption(&self) -> EncryptionAlgorithm {
132 self.default_encryption.clone()
133 }
134
135 pub fn parse(&self, data: &[u8]) -> Result<Frame> {
140 self.parse_with_fallback(data, true)
141 }
142
143 pub fn parse_with_fallback(&self, data: &[u8], allow_fallback: bool) -> Result<Frame> {
156 let decrypted = self.decrypt_data_with_fallback(data, allow_fallback)?;
158
159 let decompressed = self.decompress_data_with_fallback(&decrypted, allow_fallback)?;
161
162 self.parse_decompressed_with_fallback(&decompressed, allow_fallback)
164 }
165
166 pub fn parse_with_format(&self, data: &[u8], format: SerializationFormat) -> Result<Frame> {
168 let decrypted = self.decrypt_data(data)?;
170
171 let decompressed = self.decompress_data(&decrypted)?;
173
174 let serializer = if let Some(custom_name) = &self.custom_format_name {
176 SerializationUtil::get_serializer_by_name(custom_name)
178 } else {
179 SerializationUtil::get_serializer(format)
181 }
182 .ok_or_else(|| {
183 let format_info = if let Some(name) = &self.custom_format_name {
184 format!("custom format '{}'", name)
185 } else {
186 format!("{:?}", format)
187 };
188 crate::common::error::FlareError::deserialization_error(format!(
189 "Serializer not found: {}",
190 format_info
191 ))
192 })?;
193
194 serializer.deserialize(&decompressed)
195 }
196
197 pub fn serialize(&self, frame: &Frame) -> Result<Vec<u8>> {
199 self.serialize_with_format(
200 frame,
201 self.default_format,
202 self.default_compression.clone(),
203 self.default_encryption.clone(),
204 )
205 }
206
207 pub fn serialize_with_format(
211 &self,
212 frame: &Frame,
213 format: SerializationFormat,
214 compression: CompressionAlgorithm,
215 encryption: EncryptionAlgorithm,
216 ) -> Result<Vec<u8>> {
217 let serializer = if let Some(custom_name) = &self.custom_format_name {
219 SerializationUtil::get_serializer_by_name(custom_name)
221 } else {
222 SerializationUtil::get_serializer(format)
224 }
225 .ok_or_else(|| {
226 let format_info = if let Some(name) = &self.custom_format_name {
227 format!("custom format '{}'", name)
228 } else {
229 format!("{:?}", format)
230 };
231 crate::common::error::FlareError::encoding_error(format!(
232 "Serializer not found: {}",
233 format_info
234 ))
235 })?;
236
237 let data = serializer.serialize(frame)?;
238
239 let compressed = if Self::should_compress_payload(data.len(), &compression) {
241 CompressionUtil::compress(&data, compression)?
242 } else {
243 data
244 };
245
246 self.encrypt_data(&compressed, encryption)
248 }
249
250 pub fn serialize_with_format_compression(
252 &self,
253 frame: &Frame,
254 format: SerializationFormat,
255 compression: CompressionAlgorithm,
256 ) -> Result<Vec<u8>> {
257 self.serialize_with_format(frame, format, compression, self.default_encryption.clone())
258 }
259
260 pub fn get_compression_from_frame(frame: &Frame) -> CompressionAlgorithm {
262 frame
263 .metadata
264 .get("compression")
265 .and_then(|bytes| std::str::from_utf8(bytes).ok())
266 .and_then(CompressionAlgorithm::from_str)
267 .unwrap_or(CompressionAlgorithm::None)
268 }
269
270 pub fn should_compress_payload(payload_len: usize, compression: &CompressionAlgorithm) -> bool {
272 let _ = payload_len;
273 *compression != CompressionAlgorithm::None
274 }
275
276 pub fn get_format_from_frame(frame: &Frame) -> Option<SerializationFormat> {
278 frame
279 .metadata
280 .get("format")
281 .and_then(|bytes| std::str::from_utf8(bytes).ok())
282 .and_then(|s| {
283 if s.eq_ignore_ascii_case("protobuf") {
284 Some(SerializationFormat::Protobuf)
285 } else if s.eq_ignore_ascii_case("json") {
286 Some(SerializationFormat::Json)
287 } else {
288 None
289 }
290 })
291 }
292
293 pub fn get_encryption_from_frame(frame: &Frame) -> EncryptionAlgorithm {
295 frame
296 .metadata
297 .get("encryption")
298 .and_then(|bytes| std::str::from_utf8(bytes).ok())
299 .and_then(EncryptionAlgorithm::from_str)
300 .unwrap_or(EncryptionAlgorithm::None)
301 }
302
303 fn decrypt_data_with_fallback(&self, data: &[u8], allow_fallback: bool) -> Result<Vec<u8>> {
314 if self.default_encryption == EncryptionAlgorithm::None {
316 return Ok(data.to_vec());
317 }
318
319 let encryptor_name = self.default_encryption.as_str();
321 let encryptor = EncryptionUtil::find(&encryptor_name).ok_or_else(|| {
322 let registered = EncryptionUtil::list_registered();
324 let error_msg = format!(
325 "Encryptor '{}' not found. Registered: {:?}",
326 encryptor_name, registered
327 );
328 tracing::error!("{}", error_msg);
329 crate::common::error::FlareError::deserialization_error(error_msg)
330 })?;
331
332 match encryptor.decrypt(data) {
333 Ok(decrypted) => Ok(decrypted),
334 Err(e) => {
335 if allow_fallback {
336 tracing::trace!(
337 "解密失败,尝试作为未加密数据处理: encryption={:?}, data_len={}",
338 self.default_encryption,
339 data.len()
340 );
341 Ok(data.to_vec())
342 } else {
343 Err(crate::common::error::FlareError::deserialization_error(
344 format!(
345 "解密失败: encryption={:?}, error={}, data_len={}",
346 self.default_encryption,
347 e,
348 data.len()
349 ),
350 ))
351 }
352 }
353 }
354 }
355
356 fn decrypt_data(&self, data: &[u8]) -> Result<Vec<u8>> {
361 self.decrypt_data_with_fallback(data, true)
362 }
363
364 fn encrypt_data(&self, data: &[u8], encryption: EncryptionAlgorithm) -> Result<Vec<u8>> {
366 if encryption == EncryptionAlgorithm::None {
368 return Ok(data.to_vec());
369 }
370
371 let encryptor_name = encryption.as_str();
373 let encryptor = EncryptionUtil::find(&encryptor_name).ok_or_else(|| {
374 let registered = EncryptionUtil::list_registered();
376 let error_msg = format!(
377 "Encryptor '{}' not found. Registered: {:?}",
378 encryptor_name, registered
379 );
380 tracing::error!("{}", error_msg);
381 crate::common::error::FlareError::encoding_error(error_msg)
382 })?;
383
384 encryptor.encrypt(data)
386 }
387
388 fn decompress_data(&self, data: &[u8]) -> Result<Vec<u8>> {
390 self.decompress_data_with_fallback(data, true)
391 }
392
393 fn decompress_data_with_fallback(&self, data: &[u8], allow_fallback: bool) -> Result<Vec<u8>> {
400 if self.default_compression == CompressionAlgorithm::None {
402 return Ok(data.to_vec());
403 }
404
405 match CompressionUtil::auto_decompress(data) {
408 Ok((decompressed, detected_algorithm)) => {
409 if detected_algorithm != CompressionAlgorithm::None {
411 Ok(decompressed)
412 } else {
413 if allow_fallback {
415 tracing::trace!(
416 "自动检测未发现压缩,按阈值策略作为未压缩数据处理: compression={:?}, data_len={}",
417 self.default_compression,
418 data.len()
419 );
420 Ok(data.to_vec())
421 } else {
422 Err(crate::common::error::FlareError::deserialization_error(
424 format!(
425 "解压缩失败(严格模式): 配置了压缩 {:?} 但数据未压缩",
426 self.default_compression
427 ),
428 ))
429 }
430 }
431 }
432 Err(e) => {
433 if allow_fallback {
434 tracing::trace!(
435 "解压缩失败,尝试作为未压缩数据处理: compression={:?}, data_len={}",
436 self.default_compression,
437 data.len()
438 );
439 Ok(data.to_vec())
440 } else {
441 Err(crate::common::error::FlareError::deserialization_error(
443 format!(
444 "解压缩失败(严格模式): compression={:?}, error={}",
445 self.default_compression, e
446 ),
447 ))
448 }
449 }
450 }
451 }
452
453 #[allow(dead_code)]
455 fn parse_decompressed(&self, decompressed: &[u8]) -> Result<Frame> {
456 self.parse_decompressed_with_fallback(decompressed, true)
457 }
458
459 fn parse_decompressed_with_fallback(
466 &self,
467 decompressed: &[u8],
468 allow_fallback: bool,
469 ) -> Result<Frame> {
470 let detected_serializers = SerializationUtil::auto_detect(decompressed);
472
473 for serializer in detected_serializers {
475 if let Ok(frame) = serializer.deserialize(decompressed) {
476 return Ok(frame);
477 }
478 }
479
480 if allow_fallback {
481 self.try_all_serializers(decompressed)
483 } else {
484 let serializer = if let Some(custom_name) = &self.custom_format_name {
486 SerializationUtil::get_serializer_by_name(custom_name)
488 } else {
489 SerializationUtil::get_serializer(self.default_format)
491 }
492 .ok_or_else(|| {
493 let format_info = if let Some(name) = &self.custom_format_name {
494 format!("custom format '{}'", name)
495 } else {
496 format!("format {:?}", self.default_format)
497 };
498 crate::common::error::FlareError::deserialization_error(format!(
499 "Serializer not found for {}",
500 format_info
501 ))
502 })?;
503 serializer.deserialize(decompressed).map_err(|e| {
504 let format_info = if let Some(name) = &self.custom_format_name {
505 format!("custom format '{}'", name)
506 } else {
507 format!("format {:?}", self.default_format)
508 };
509 crate::common::error::FlareError::deserialization_error(format!(
510 "反序列化失败(严格模式): {}, error={}",
511 format_info, e
512 ))
513 })
514 }
515 }
516
517 fn try_all_serializers(&self, data: &[u8]) -> Result<Frame> {
519 [SerializationFormat::Protobuf, SerializationFormat::Json]
520 .iter()
521 .find_map(|&format| {
522 SerializationUtil::get_serializer(format)
523 .and_then(|serializer| serializer.deserialize(data).ok())
524 })
525 .ok_or_else(|| {
526 crate::common::error::FlareError::deserialization_error(
527 "Failed to parse message: no compatible serializer found".to_string(),
528 )
529 })
530 }
531}
532
533#[cfg(test)]
534mod tests {
535 use super::*;
536 use crate::common::protocol::{FrameBuilder, ping};
537
538 #[test]
539 fn test_parse_protobuf() {
540 let parser = MessageParser::protobuf();
541 let frame = FrameBuilder::new()
542 .with_command(crate::common::protocol::Command {
543 r#type: Some(
544 crate::common::protocol::flare::core::commands::command::Type::System(ping()),
545 ),
546 })
547 .build();
548
549 let data = parser.serialize(&frame).unwrap();
550 let parsed = parser.parse(&data).unwrap();
551 assert_eq!(parsed.message_id, frame.message_id);
552 }
553
554 #[test]
555 fn test_parse_json() {
556 let parser = &PRE_NEGOTIATION_PARSER;
557 let frame = FrameBuilder::new()
558 .with_command(crate::common::protocol::Command {
559 r#type: Some(
560 crate::common::protocol::flare::core::commands::command::Type::System(ping()),
561 ),
562 })
563 .build();
564
565 let data = parser.serialize(&frame).unwrap();
566 let parsed = parser.parse(&data).unwrap();
567 assert_eq!(parsed.message_id, frame.message_id);
568 }
569
570 #[test]
571 #[cfg(feature = "compression-gzip")]
572 fn small_payload_uses_negotiated_compression_and_strict_parse_accepts_it() {
573 let parser = MessageParser::new(
574 SerializationFormat::Protobuf,
575 CompressionAlgorithm::Gzip,
576 EncryptionAlgorithm::None,
577 );
578 let frame = FrameBuilder::new()
579 .with_command(crate::common::protocol::Command {
580 r#type: Some(
581 crate::common::protocol::flare::core::commands::command::Type::System(ping()),
582 ),
583 })
584 .build();
585
586 let data = parser.serialize(&frame).unwrap();
587 let (_, detected) = CompressionUtil::auto_decompress(&data).unwrap();
588 assert_eq!(detected, CompressionAlgorithm::Gzip);
589
590 let parsed = parser.parse_with_fallback(&data, false).unwrap();
591 assert_eq!(parsed.message_id, frame.message_id);
592 }
593
594 #[test]
595 #[cfg(feature = "compression-gzip")]
596 fn large_payload_uses_negotiated_compression() {
597 let parser = MessageParser::new(
598 SerializationFormat::Protobuf,
599 CompressionAlgorithm::Gzip,
600 EncryptionAlgorithm::None,
601 );
602 let frame = FrameBuilder::new()
603 .with_metadata(
604 "padding".to_string(),
605 vec![b'x'; MIN_COMPRESSION_PAYLOAD_BYTES * 2],
606 )
607 .build();
608
609 let data = parser.serialize(&frame).unwrap();
610 let (_, detected) = CompressionUtil::auto_decompress(&data).unwrap();
611 assert_eq!(detected, CompressionAlgorithm::Gzip);
612
613 let parsed = parser.parse_with_fallback(&data, false).unwrap();
614 assert_eq!(parsed.message_id, frame.message_id);
615 }
616
617 #[test]
618 fn test_get_encryption_from_frame() {
619 use crate::common::protocol::FrameBuilder;
620 use std::collections::HashMap;
621
622 let frame = FrameBuilder::new().build();
624 assert_eq!(
625 MessageParser::get_encryption_from_frame(&frame),
626 EncryptionAlgorithm::None
627 );
628
629 let mut metadata = HashMap::new();
631 metadata.insert("encryption".to_string(), b"aes256gcm".to_vec());
632 let frame = FrameBuilder::new()
633 .with_metadata("encryption".to_string(), b"aes256gcm".to_vec())
634 .build();
635 assert_eq!(
636 MessageParser::get_encryption_from_frame(&frame),
637 EncryptionAlgorithm::Aes256Gcm
638 );
639
640 let frame = FrameBuilder::new()
642 .with_metadata("encryption".to_string(), b"invalid".to_vec())
643 .build();
644 assert_eq!(
645 MessageParser::get_encryption_from_frame(&frame),
646 EncryptionAlgorithm::Custom("invalid".to_string())
647 );
648 }
649}