Allow uncapped/growable packet sizes

This commit is contained in:
NGnius 2022-08-01 12:23:57 -04:00
parent ac03348e96
commit 424acdf694
8 changed files with 177 additions and 186 deletions

View file

@ -125,9 +125,10 @@ impl Instance {
)
}
};
let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
//let mut buffer = [0u8; socket::PACKET_BUFFER_SIZE];
let mut buffer = String::with_capacity(socket::PACKET_BUFFER_SIZE);
let response = Self::handle_call(packet, &handlers);
let len = match response.dump_base64(&mut buffer) {
let _len = match response.dump_base64(&mut buffer) {
Ok(x) => x,
Err(_) => {
return warp::reply::with_status(
@ -137,9 +138,8 @@ impl Instance {
)
}
};
let string: String = String::from_utf8_lossy(&buffer[..len]).into();
warp::reply::with_status(
warp::http::Response::builder().body(string),
warp::http::Response::builder().body(buffer),
warp::http::StatusCode::from_u16(200).unwrap(),
)
})
@ -165,7 +165,7 @@ impl Instance {
}
};
let mut buffer = Vec::with_capacity(socket::PACKET_BUFFER_SIZE);
buffer.extend(&[0u8; socket::PACKET_BUFFER_SIZE]);
//buffer.extend(&[0u8; socket::PACKET_BUFFER_SIZE]);
let response = Self::handle_call(packet, &handlers);
let len = match response.dump_encrypted(&mut buffer, &key, &NONCE) {
Ok(x) => x,

View file

@ -1,3 +1,5 @@
use std::io::{Read, Write};
use crate::serdes::{DumpError, Dumpable, LoadError, Loadable, Primitive};
/// Remote call packet representing a function to call on the back-end, sent from the front-end
@ -11,10 +13,10 @@ pub struct RemoteCall {
}
impl Loadable for RemoteCall {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let (id_num, len0) = u64::load(buffer)?;
let (function_name, len1) = String::load(&buffer[len0..])?;
let (params, len2) = Vec::<Primitive>::load(&buffer[len0 + len1..])?;
let (function_name, len1) = String::load(buffer)?;
let (params, len2) = Vec::<Primitive>::load(buffer)?;
Ok((
Self {
id: id_num,
@ -27,10 +29,10 @@ impl Loadable for RemoteCall {
}
impl Dumpable for RemoteCall {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
let len0 = self.id.dump(buffer)?;
let len1 = self.function.dump(&mut buffer[len0..])?;
let len2 = self.parameters.dump(&mut buffer[len0 + len1..])?;
let len1 = self.function.dump(buffer)?;
let len2 = self.parameters.dump(buffer)?;
Ok(len0 + len1 + len2)
}
}
@ -44,9 +46,9 @@ pub struct RemoteCallResponse {
}
impl Loadable for RemoteCallResponse {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let (id_num, len0) = u64::load(buffer)?;
let (response_var, len1) = Vec::<Primitive>::load(&buffer[len0..])?;
let (response_var, len1) = Vec::<Primitive>::load(buffer)?;
Ok((
Self {
id: id_num,
@ -58,9 +60,9 @@ impl Loadable for RemoteCallResponse {
}
impl Dumpable for RemoteCallResponse {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
let len0 = self.id.dump(buffer)?;
let len1 = self.response.dump(&mut buffer[len0..])?;
let len1 = self.response.dump(buffer)?;
Ok(len0 + len1)
}
}

View file

@ -1,88 +1,70 @@
use std::io::Write;
use super::{DumpError, Dumpable};
impl Dumpable for String {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
let str_bytes = self.as_bytes();
let len_bytes = (str_bytes.len() as u32).to_le_bytes();
let total_len = str_bytes.len() + 4;
if buffer.len() < total_len {
return Err(DumpError::TooSmallBuffer);
}
(&mut buffer[..4]).copy_from_slice(&len_bytes);
(&mut buffer[4..total_len]).copy_from_slice(str_bytes);
Ok(total_len)
let size1 = buffer.write(&len_bytes).map_err(DumpError::Io)?;
let size2 = buffer.write(&str_bytes).map_err(DumpError::Io)?;
Ok(size1 + size2)
}
}
impl<T: Dumpable> Dumpable for Vec<T> {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
let len_bytes = (self.len() as u32).to_le_bytes();
(&mut buffer[..4]).copy_from_slice(&len_bytes);
let mut cursor = 4;
let mut total = buffer.write(&len_bytes).map_err(DumpError::Io)?;
for obj in self.iter() {
let len = obj.dump(&mut buffer[cursor..])?;
cursor += len;
let len = obj.dump(buffer)?;
total += len;
}
Ok(cursor)
Ok(total)
}
}
impl Dumpable for bool {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
if buffer.len() < 1 {
return Err(DumpError::TooSmallBuffer);
}
buffer[0] = *self as u8;
Ok(1)
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
buffer.write(&[*self as u8]).map_err(DumpError::Io)
}
}
impl Dumpable for u8 {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
if buffer.len() < 1 {
return Err(DumpError::TooSmallBuffer);
}
buffer[0] = *self;
Ok(1)
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
buffer.write(&[*self]).map_err(DumpError::Io)
}
}
impl Dumpable for i8 {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
if buffer.len() < 1 {
return Err(DumpError::TooSmallBuffer);
/*impl Dumpable for i8 {
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
buffer.write(&self.to_le_bytes()).map_err(DumpError::Io)
}
buffer[0] = self.to_le_bytes()[0];
Ok(1)
}
}
}*/
macro_rules! int_impl {
($type:ty, $size:literal) => {
($type:ty) => {
impl Dumpable for $type {
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
if buffer.len() < $size {
return Err(DumpError::TooSmallBuffer);
}
(&mut buffer[..$size]).copy_from_slice(&self.to_le_bytes());
Ok($size)
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError> {
buffer.write(&self.to_le_bytes()).map_err(DumpError::Io)
}
}
};
}
int_impl! {u16, 2}
int_impl! {u32, 4}
int_impl! {u64, 8}
int_impl! {u128, 16}
int_impl! {u16}
int_impl! {u32}
int_impl! {u64}
int_impl! {u128}
int_impl! {i16, 2}
int_impl! {i32, 4}
int_impl! {i64, 8}
int_impl! {i128, 16}
int_impl! {i8}
int_impl! {i16}
int_impl! {i32}
int_impl! {i64}
int_impl! {i128}
int_impl! {f32, 4}
int_impl! {f64, 8}
int_impl! {f32}
int_impl! {f64}
#[cfg(test)]
mod tests {
@ -93,10 +75,11 @@ mod tests {
#[test]
fn $fn_name() {
let data = $data;
let mut buffer = [0u8; 128];
let mut buffer = Vec::with_capacity(128);
let write_len = data.dump(&mut buffer).expect("Dump not ok");
assert_eq!(write_len, $expected_len, "Wrong amount written");
assert_eq!(&buffer[..write_len], $expected_dump);
println!("Dumped {:?}", buffer.as_slice());
}
};
}

View file

@ -1,32 +1,36 @@
use std::io::Read;
use super::{LoadError, Loadable};
impl Loadable for String {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
if buffer.len() < 4 {
return Err(LoadError::TooSmallBuffer);
}
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut u32_bytes: [u8; 4] = [u8::MAX; 4];
u32_bytes.copy_from_slice(&buffer[..4]);
buffer.read_exact(&mut u32_bytes).map_err(LoadError::Io)?;
let str_size = u32::from_le_bytes(u32_bytes) as usize;
//let mut str_buf = String::with_capacity(str_size);
let mut str_buf = Vec::with_capacity(str_size);
let mut byte_buf = [u8::MAX; 1];
for _ in 0..str_size {
buffer.read_exact(&mut byte_buf).map_err(LoadError::Io)?;
str_buf.push(byte_buf[0]);
}
//let size2 = buffer.read_to_string(&mut str_buf).map_err(LoadError::Io)?;
Ok((
Self::from_utf8_lossy(&buffer[4..str_size + 4]).into_owned(),
String::from_utf8(str_buf).map_err(|_| LoadError::InvalidData)?,
str_size + 4,
))
}
}
impl<T: Loadable> Loadable for Vec<T> {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
if buffer.len() < 4 {
return Err(LoadError::TooSmallBuffer);
}
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut u32_bytes: [u8; 4] = [u8::MAX; 4];
u32_bytes.copy_from_slice(&buffer[..4]);
buffer.read_exact(&mut u32_bytes).map_err(LoadError::Io)?;
let count = u32::from_le_bytes(u32_bytes) as usize;
let mut cursor = 4;
let mut items = Vec::with_capacity(count);
for _ in 0..count {
let (obj, len) = T::load(&buffer[cursor..])?;
let (obj, len) = T::load(buffer)?;
cursor += len;
items.push(obj);
}
@ -35,41 +39,35 @@ impl<T: Loadable> Loadable for Vec<T> {
}
impl Loadable for bool {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
if buffer.len() < 1 {
return Err(LoadError::TooSmallBuffer);
}
Ok((buffer[0] != 0, 1))
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut byte = [u8::MAX; 1];
buffer.read_exact(&mut byte).map_err(LoadError::Io)?;
Ok((byte[0] != 0, 1))
}
}
impl Loadable for u8 {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
if buffer.len() < 1 {
return Err(LoadError::TooSmallBuffer);
}
Ok((buffer[0], 1))
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut byte = [u8::MAX; 1];
buffer.read_exact(&mut byte).map_err(LoadError::Io)?;
Ok((byte[0], 1))
}
}
impl Loadable for i8 {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
if buffer.len() < 1 {
return Err(LoadError::TooSmallBuffer);
}
Ok((i8::from_le_bytes([buffer[0]]), 1))
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut byte = [u8::MAX; 1];
buffer.read_exact(&mut byte).map_err(LoadError::Io)?;
Ok((i8::from_le_bytes(byte), 1))
}
}
macro_rules! int_impl {
($type:ty, $size:literal) => {
impl Loadable for $type {
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
if buffer.len() < $size {
return Err(LoadError::TooSmallBuffer);
}
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut bytes: [u8; $size] = [u8::MAX; $size];
bytes.copy_from_slice(&buffer[..$size]);
buffer.read_exact(&mut bytes).map_err(LoadError::Io)?;
let i = <$type>::from_le_bytes(bytes);
Ok((i, $size))
}
@ -93,15 +91,19 @@ int_impl! {f64, 8}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Cursor;
macro_rules! test_impl {
($fn_name:ident, $data:expr, $type:ty, $expected_len:literal, $expected_load:expr) => {
#[test]
fn $fn_name() {
let buffer = $data;
let (obj, read_len) = <$type>::load(&buffer).expect("Load not ok");
let buffer_data = $data;
let mut buffer = Vec::with_capacity(buffer_data.len());
buffer.extend_from_slice(&buffer_data);
let (obj, read_len) = <$type>::load(&mut Cursor::new(buffer)).expect("Load not ok");
assert_eq!(read_len, $expected_len, "Wrong amount read");
assert_eq!(obj, $expected_load, "Loaded value not as expected");
println!("Loaded {:?}", obj);
}
};
}

View file

@ -1,3 +1,4 @@
use std::io::{Read, Write};
use super::{DumpError, Dumpable, LoadError, Loadable};
/// Primitive types supported for communication between the USDPL back- and front-end.
@ -44,22 +45,21 @@ impl Primitive {
}
impl Loadable for Primitive {
fn load(buf: &[u8]) -> Result<(Self, usize), LoadError> {
if buf.len() == 0 {
return Err(LoadError::TooSmallBuffer);
}
let mut result: (Self, usize) = match buf[0] {
fn load(buf: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut discriminant_buf = [u8::MAX; 1];
buf.read_exact(&mut discriminant_buf).map_err(LoadError::Io)?;
let mut result: (Self, usize) = match discriminant_buf[0] {
//0 => (None, 0),
1 => (Self::Empty, 0),
2 => String::load(&buf[1..]).map(|(obj, len)| (Self::String(obj), len))?,
3 => f32::load(&buf[1..]).map(|(obj, len)| (Self::F32(obj), len))?,
4 => f64::load(&buf[1..]).map(|(obj, len)| (Self::F64(obj), len))?,
5 => u32::load(&buf[1..]).map(|(obj, len)| (Self::U32(obj), len))?,
6 => u64::load(&buf[1..]).map(|(obj, len)| (Self::U64(obj), len))?,
7 => i32::load(&buf[1..]).map(|(obj, len)| (Self::I32(obj), len))?,
8 => i64::load(&buf[1..]).map(|(obj, len)| (Self::I64(obj), len))?,
9 => bool::load(&buf[1..]).map(|(obj, len)| (Self::Bool(obj), len))?,
10 => String::load(&buf[1..]).map(|(obj, len)| (Self::Json(obj), len))?,
2 => String::load(buf).map(|(obj, len)| (Self::String(obj), len))?,
3 => f32::load(buf).map(|(obj, len)| (Self::F32(obj), len))?,
4 => f64::load(buf).map(|(obj, len)| (Self::F64(obj), len))?,
5 => u32::load(buf).map(|(obj, len)| (Self::U32(obj), len))?,
6 => u64::load(buf).map(|(obj, len)| (Self::U64(obj), len))?,
7 => i32::load(buf).map(|(obj, len)| (Self::I32(obj), len))?,
8 => i64::load(buf).map(|(obj, len)| (Self::I64(obj), len))?,
9 => bool::load(buf).map(|(obj, len)| (Self::Bool(obj), len))?,
10 => String::load(buf).map(|(obj, len)| (Self::Json(obj), len))?,
_ => return Err(LoadError::InvalidData),
};
result.1 += 1;
@ -68,25 +68,21 @@ impl Loadable for Primitive {
}
impl Dumpable for Primitive {
fn dump(&self, buf: &mut [u8]) -> Result<usize, DumpError> {
if buf.len() == 0 {
return Err(DumpError::TooSmallBuffer);
}
buf[0] = self.discriminant();
let mut result = match self {
fn dump(&self, buf: &mut dyn Write) -> Result<usize, DumpError> {
let size1 = buf.write(&[self.discriminant()]).map_err(DumpError::Io)?;
let result = match self {
Self::Empty => Ok(0),
Self::String(s) => s.dump(&mut buf[1..]),
Self::F32(x) => x.dump(&mut buf[1..]),
Self::F64(x) => x.dump(&mut buf[1..]),
Self::U32(x) => x.dump(&mut buf[1..]),
Self::U64(x) => x.dump(&mut buf[1..]),
Self::I32(x) => x.dump(&mut buf[1..]),
Self::I64(x) => x.dump(&mut buf[1..]),
Self::Bool(x) => x.dump(&mut buf[1..]),
Self::Json(x) => x.dump(&mut buf[1..]),
Self::String(s) => s.dump(buf),
Self::F32(x) => x.dump(buf),
Self::F64(x) => x.dump(buf),
Self::U32(x) => x.dump(buf),
Self::U64(x) => x.dump(buf),
Self::I32(x) => x.dump(buf),
Self::I64(x) => x.dump(buf),
Self::Bool(x) => x.dump(buf),
Self::Json(x) => x.dump(buf),
}?;
result += 1;
Ok(result)
Ok(size1 + result)
}
}
@ -127,14 +123,15 @@ into_impl! {f64, F64}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Cursor;
#[test]
fn string_idempotence_test() {
let data = "Test";
let primitive = Primitive::String(data.to_string());
let mut buffer = [0u8; 128];
let mut buffer = Vec::with_capacity(128);
let write_len = primitive.dump(&mut buffer).expect("Dump not ok");
let (obj, read_len) = Primitive::load(&buffer).expect("Load not ok");
let (obj, read_len) = Primitive::load(&mut Cursor::new(buffer)).expect("Load not ok");
assert_eq!(
write_len, read_len,
"Amount written and amount read do not match"
@ -149,9 +146,9 @@ mod tests {
#[test]
fn empty_idempotence_test() {
let primitive = Primitive::Empty;
let mut buffer = [0u8; 128];
let mut buffer = Vec::with_capacity(128);
let write_len = primitive.dump(&mut buffer).expect("Dump not ok");
let (obj, read_len) = Primitive::load(&buffer).expect("Load not ok");
let (obj, read_len) = Primitive::load(&mut Cursor::new(buffer)).expect("Load not ok");
assert_eq!(
write_len, read_len,
"Amount written and amount read do not match"

View file

@ -1,4 +1,5 @@
use base64::{decode_config_slice, encode_config_slice, Config};
use std::io::{Read, Write, Cursor};
use base64::{decode_config_buf, encode_config_buf, Config};
const B64_CONF: Config = Config::new(base64::CharacterSet::Standard, true);
@ -18,6 +19,8 @@ pub enum LoadError {
/// Encrypted data cannot be decrypted
#[cfg(feature = "encrypt")]
DecryptionError,
/// Read error
Io(std::io::Error),
/// Unimplemented
#[cfg(debug_assertions)]
Todo,
@ -30,6 +33,7 @@ impl std::fmt::Display for LoadError {
Self::InvalidData => write!(f, "LoadError: InvalidData"),
#[cfg(feature = "encrypt")]
Self::DecryptionError => write!(f, "LoadError: DecryptionError"),
Self::Io(err) => write!(f, "LoadError: Io({})", err),
#[cfg(debug_assertions)]
Self::Todo => write!(f, "LoadError: TODO!"),
}
@ -39,30 +43,33 @@ impl std::fmt::Display for LoadError {
/// Load an object from the buffer
pub trait Loadable: Sized {
/// Read the buffer, building the object and returning the amount of bytes read.
/// If anything is wrong with the buffer, None should be returned.
fn load(buffer: &[u8]) -> Result<(Self, usize), LoadError>;
/// If anything is wrong with the buffer, Err should be returned.
fn load(buffer: &mut dyn Read) -> Result<(Self, usize), LoadError>;
/// Load data from a base64-encoded buffer
fn load_base64(buffer: &[u8]) -> Result<(Self, usize), LoadError> {
let mut buffer2 = [0u8; crate::socket::PACKET_BUFFER_SIZE];
let len = decode_config_slice(buffer, B64_CONF, &mut buffer2)
let mut buffer2 = Vec::with_capacity(crate::socket::PACKET_BUFFER_SIZE);
decode_config_buf(buffer, B64_CONF, &mut buffer2)
.map_err(|_| LoadError::InvalidData)?;
Self::load(&buffer2[..len])
let mut cursor = Cursor::new(buffer2);
Self::load(&mut cursor)
}
/// Load data from an encrypted base64-encoded buffer
#[cfg(feature = "encrypt")]
fn load_encrypted(buffer: &[u8], key: &[u8], nonce: &[u8]) -> Result<(Self, usize), LoadError> {
println!("encrypted buffer: {}", String::from_utf8(buffer.to_vec()).unwrap());
//println!("encrypted buffer: {}", String::from_utf8(buffer.to_vec()).unwrap());
let key = aes_gcm_siv::Key::from_slice(key);
let cipher = aes_gcm_siv::Aes256GcmSiv::new(key);
let nonce = aes_gcm_siv::Nonce::from_slice(nonce);
let mut decoded_buf = base64::decode_config(buffer, B64_CONF)
let mut decoded_buf = Vec::with_capacity(crate::socket::PACKET_BUFFER_SIZE);
base64::decode_config_buf(buffer, B64_CONF, &mut decoded_buf)
.map_err(|_| LoadError::InvalidData)?;
println!("Decoded buf: {:?}", decoded_buf);
//println!("Decoded buf: {:?}", decoded_buf);
cipher.decrypt_in_place(nonce, ASSOCIATED_DATA, &mut decoded_buf).map_err(|_| LoadError::DecryptionError)?;
println!("Decrypted buf: {:?}", decoded_buf);
Self::load(decoded_buf.as_slice())
//println!("Decrypted buf: {:?}", decoded_buf);
let mut cursor = Cursor::new(decoded_buf);
Self::load(&mut cursor)
}
}
@ -76,6 +83,8 @@ pub enum DumpError {
/// Data cannot be encrypted
#[cfg(feature = "encrypt")]
EncryptionError,
/// Write error
Io(std::io::Error),
/// Unimplemented
#[cfg(debug_assertions)]
Todo,
@ -88,6 +97,7 @@ impl std::fmt::Display for DumpError {
Self::Unsupported => write!(f, "DumpError: Unsupported"),
#[cfg(feature = "encrypt")]
Self::EncryptionError => write!(f, "DumpError: EncryptionError"),
Self::Io(err) => write!(f, "DumpError: Io({})", err),
#[cfg(debug_assertions)]
Self::Todo => write!(f, "DumpError: TODO!"),
}
@ -98,33 +108,35 @@ impl std::fmt::Display for DumpError {
pub trait Dumpable {
/// Write the object to the buffer, returning the amount of bytes written.
/// If anything is wrong, false should be returned.
fn dump(&self, buffer: &mut [u8]) -> Result<usize, DumpError>;
fn dump(&self, buffer: &mut dyn Write) -> Result<usize, DumpError>;
/// Dump data as base64-encoded.
/// Useful for transmitting data as text.
fn dump_base64(&self, buffer: &mut [u8]) -> Result<usize, DumpError> {
let mut buffer2 = [0u8; crate::socket::PACKET_BUFFER_SIZE];
fn dump_base64(&self, buffer: &mut String) -> Result<usize, DumpError> {
let mut buffer2 = Vec::with_capacity(crate::socket::PACKET_BUFFER_SIZE);
let len = self.dump(&mut buffer2)?;
let len = encode_config_slice(&buffer2[..len], B64_CONF, buffer);
encode_config_buf(&buffer2[..len], B64_CONF, buffer);
Ok(len)
}
/// Dump data as an encrypted base64-encoded buffer
#[cfg(feature = "encrypt")]
fn dump_encrypted(&self, buffer: &mut Vec<u8>, key: &[u8], nonce: &[u8]) -> Result<usize, DumpError> {
let mut buffer2 = Vec::with_capacity(buffer.capacity());
buffer2.extend_from_slice(buffer.as_slice());
let mut buffer2 = Vec::with_capacity(crate::socket::PACKET_BUFFER_SIZE);
let size = self.dump(&mut buffer2)?;
buffer2.truncate(size);
println!("Buf: {:?}", buffer2);
//println!("Buf: {:?}", buffer2);
let key = aes_gcm_siv::Key::from_slice(key);
let cipher = aes_gcm_siv::Aes256GcmSiv::new(key);
let nonce = aes_gcm_siv::Nonce::from_slice(nonce);
cipher.encrypt_in_place(nonce, ASSOCIATED_DATA, &mut buffer2).map_err(|_| DumpError::EncryptionError)?;
println!("Encrypted slice: {:?}", &buffer2);
let size = encode_config_slice(buffer2.as_slice(), B64_CONF, buffer);
let string = String::from_utf8(buffer.as_slice()[..size].to_vec()).unwrap();
println!("Encoded slice: {}", string);
Ok(size)
//println!("Encrypted slice: {:?}", &buffer2);
let mut base64_buf = String::with_capacity(crate::socket::PACKET_BUFFER_SIZE);
encode_config_buf(buffer2.as_slice(), B64_CONF, &mut base64_buf);
//println!("base64 len: {}", base64_buf.as_bytes().len());
buffer.extend_from_slice(base64_buf.as_bytes());
//let string = String::from_utf8(buffer.as_slice().to_vec()).unwrap();
//println!("Encoded slice: {}", string);
Ok(base64_buf.len())
}
}

View file

@ -1,5 +1,6 @@
//! Web messaging
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
use std::io::{Read, Write};
use crate::serdes::{DumpError, Dumpable, LoadError, Loadable};
use crate::{RemoteCall, RemoteCallResponse};
@ -57,30 +58,29 @@ impl Packet {
}
impl Loadable for Packet {
fn load(buf: &[u8]) -> Result<(Self, usize), LoadError> {
if buf.len() == 0 {
return Err(LoadError::TooSmallBuffer);
}
let mut result: (Self, usize) = match buf[0] {
fn load(buf: &mut dyn Read) -> Result<(Self, usize), LoadError> {
let mut discriminant_buf = [u8::MAX; 1];
buf.read_exact(&mut discriminant_buf).map_err(LoadError::Io)?;
let mut result: (Self, usize) = match discriminant_buf[0] {
//0 => (None, 0),
1 => {
let (obj, len) = RemoteCall::load(&buf[1..])?;
let (obj, len) = RemoteCall::load(buf)?;
(Self::Call(obj), len)
}
2 => {
let (obj, len) = RemoteCallResponse::load(&buf[1..])?;
let (obj, len) = RemoteCallResponse::load(buf)?;
(Self::CallResponse(obj), len)
}
3 => (Self::KeepAlive, 0),
4 => (Self::Invalid, 0),
5 => {
let (obj, len) = String::load(&buf[1..])?;
let (obj, len) = String::load(buf)?;
(Self::Message(obj), len)
}
6 => (Self::Unsupported, 0),
7 => return Err(LoadError::InvalidData),
8 => {
let (obj, len) = <_>::load(&buf[1..])?;
let (obj, len) = <_>::load(buf)?;
(Self::Many(obj), len)
}
_ => return Err(LoadError::InvalidData),
@ -91,23 +91,19 @@ impl Loadable for Packet {
}
impl Dumpable for Packet {
fn dump(&self, buf: &mut [u8]) -> Result<usize, DumpError> {
if buf.len() == 0 {
return Err(DumpError::TooSmallBuffer);
}
buf[0] = self.discriminant();
let mut result = match self {
Self::Call(c) => c.dump(&mut buf[1..]),
Self::CallResponse(c) => c.dump(&mut buf[1..]),
fn dump(&self, buf: &mut dyn Write) -> Result<usize, DumpError> {
let size1 = buf.write(&[self.discriminant()]).map_err(DumpError::Io)?;
let result = match self {
Self::Call(c) => c.dump(buf),
Self::CallResponse(c) => c.dump(buf),
Self::KeepAlive => Ok(0),
Self::Invalid => Ok(0),
Self::Message(s) => s.dump(&mut buf[1..]),
Self::Message(s) => s.dump(buf),
Self::Unsupported => Ok(0),
Self::Bad => return Err(DumpError::Unsupported),
Self::Many(v) => v.dump(&mut buf[1..]),
Self::Many(v) => v.dump(buf),
}?;
result += 1;
Ok(result)
Ok(size1 + result)
}
}
@ -126,7 +122,6 @@ mod tests {
parameters: Vec::new(),
});
let mut buffer = Vec::with_capacity(PACKET_BUFFER_SIZE);
buffer.extend_from_slice(&[0u8; PACKET_BUFFER_SIZE]);
let len = packet.dump_encrypted(&mut buffer, &key, &nonce).unwrap();
println!("buffer: {}", String::from_utf8(buffer.as_slice()[..len].to_vec()).unwrap());

View file

@ -80,7 +80,7 @@ pub async fn send_js(
#[cfg(feature = "encrypt")]
fn dump_to_buffer(packet: socket::Packet, key: &[u8]) -> Result<(Vec<u8>, usize), JsValue> {
let mut buffer = Vec::with_capacity(socket::PACKET_BUFFER_SIZE);
buffer.extend_from_slice(&[0u8; socket::PACKET_BUFFER_SIZE]);
//buffer.extend_from_slice(&[0u8; socket::PACKET_BUFFER_SIZE]);
let len = packet
.dump_encrypted(&mut buffer, key, &NONCE)
.map_err(super::convert::str_to_js)?;
@ -89,10 +89,10 @@ fn dump_to_buffer(packet: socket::Packet, key: &[u8]) -> Result<(Vec<u8>, usize)
#[cfg(not(feature = "encrypt"))]
fn dump_to_buffer(packet: socket::Packet) -> Result<(Vec<u8>, usize), JsValue> {
let mut buffer = Vec::with_capacity(socket::PACKET_BUFFER_SIZE);
buffer.extend_from_slice(&[0u8; socket::PACKET_BUFFER_SIZE]);
let mut buffer = String::with_capacity(socket::PACKET_BUFFER_SIZE);
//buffer.extend_from_slice(&[0u8; socket::PACKET_BUFFER_SIZE]);
let len = packet
.dump_base64(buffer.as_mut_slice())
.dump_base64(&mut buffer)
.map_err(super::convert::str_to_js)?;
Ok((buffer, len))
Ok((buffer.as_bytes().to_vec(), len))
}