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