Mercurial > core / rust/lib/net/src/codec/dm.rs
changeset 698: |
96958d3eb5b0 |
parent: |
c7165d93a9eb
|
author: |
Richard Westhaver <ellis@rwest.io> |
date: |
Fri, 04 Oct 2024 22:04:59 -0400 |
permissions: |
-rw-r--r-- |
description: |
fixes |
1 //! A state-less messaging protocol 2 use tokio_util::codec::{Encoder, Decoder}; 3 use bytes::{BytesMut, Buf}; 7 pub const MAX: usize = usize::MAX; 14 #[derive(Debug, Clone, Copy)] 15 pub enum DecodeState { 20 impl Encoder<String> for DmCodec { 21 type Error = std::io::Error; 22 fn encode(&mut self, item: String, dst: &mut BytesMut) -> Result<(), Self::Error> { 23 // Don't send a string if it is longer than the other end will 26 return Err(std::io::Error::new( 27 std::io::ErrorKind::InvalidData, 28 format!("Frame of length {} is too large.", item.len()) 32 // Convert the length into a byte array. 33 // The cast to u32 cannot overflow due to the length check above. 34 let len_slice = u32::to_le_bytes(item.len() as u32); 36 // Reserve space in the buffer. 37 dst.reserve(4 + item.len()); 39 // Write the length and string to the buffer. 40 dst.extend_from_slice(&len_slice); 41 dst.extend_from_slice(item.as_bytes()); 46 impl Decoder for DmCodec { 48 type Error = std::io::Error; 53 ) -> Result<Option<Self::Item>, Self::Error> { 55 // Not enough data to read length marker. 59 // Read length marker. 60 let mut length_bytes = [0u8; 4]; 61 length_bytes.copy_from_slice(&src[..4]); 62 let length = u32::from_le_bytes(length_bytes) as usize; 64 // Check that the length is not too large to avoid a denial of 65 // service attack where the server runs out of memory. 67 return Err(std::io::Error::new( 68 std::io::ErrorKind::InvalidData, 69 format!("Frame of length {} is too large.", length) 73 if src.len() < 4 + length { 74 // The full string has not yet arrived. 76 // We reserve more space in the buffer. This is not strictly 77 // necessary, but is a good idea performance-wise. 78 src.reserve(4 + length - src.len()); 80 // We inform the Framed that we need more bytes to form the next 85 // Use advance to modify src such that it no longer contains 87 let data = src[4..4 + length].to_vec(); 88 src.advance(4 + length); 90 // Convert the data to a string, or fail if it is not valid utf-8. 91 match String::from_utf8(data) { 92 Ok(string) => Ok(Some(string)), 94 Err(std::io::Error::new( 95 std::io::ErrorKind::InvalidData, 96 utf8_error.utf8_error(),