chunked reading

This commit is contained in:
MeexReay 2025-02-12 16:56:20 +03:00
parent a2be0e3235
commit 95dcb095fb
4 changed files with 62 additions and 16 deletions

View File

@ -34,6 +34,11 @@ impl ChatStorage {
self.packet_size.store(packet_size, Ordering::SeqCst); self.packet_size.store(packet_size, Ordering::SeqCst);
*self.messages.write().unwrap() = messages; *self.messages.write().unwrap() = messages;
} }
pub fn append(&self, messages: Vec<String>, packet_size: usize) {
self.packet_size.store(packet_size, Ordering::SeqCst);
self.messages.write().unwrap().append(&mut messages.clone());
}
} }
@ -67,7 +72,13 @@ Press enter to close")?;
let message = format!("Checking ping... {:X}", random::<u16>()); let message = format!("Checking ping... {:X}", random::<u16>());
send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?; send_message(&mut connect(&ctx.host, ctx.enable_ssl)?, &message)?;
loop { loop {
let data = read_messages(&mut connect(&ctx.host, ctx.enable_ssl)?, ctx.max_messages, before, !ctx.enable_ssl).ok().flatten(); let data = read_messages(
&mut connect(&ctx.host, ctx.enable_ssl)?,
ctx.max_messages,
before,
!ctx.enable_ssl,
ctx.enable_chunked
).ok().flatten();
if let Some((data, size)) = data { if let Some((data, size)) = data {
if let Some(last) = data.iter().rev().find(|o| o.contains(&message)) { if let Some(last) = data.iter().rev().find(|o| o.contains(&message)) {
@ -95,6 +106,7 @@ pub fn print_console(ctx: Arc<Context>, messages: Vec<String>, input: &str) -> R
let mut messages = messages let mut messages = messages
.into_iter() .into_iter()
.flat_map(|o| string_chunks(&o, width as usize - 1)) .flat_map(|o| string_chunks(&o, width as usize - 1))
.map(|o| (o.0.white().blink().to_string(), o.1))
.collect::<Vec<(String, usize)>>(); .collect::<Vec<(String, usize)>>();
let messages_size = if messages.len() >= height { let messages_size = if messages.len() >= height {
@ -478,15 +490,27 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
} }
pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> { pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
match read_messages(&mut connect(&ctx.host, ctx.enable_ssl)?, ctx.max_messages, ctx.messages.packet_size(), !ctx.enable_ssl) { match read_messages(
&mut connect(&ctx.host, ctx.enable_ssl)?,
ctx.max_messages,
ctx.messages.packet_size(),
!ctx.enable_ssl,
ctx.enable_chunked
) {
Ok(Some((messages, size))) => { Ok(Some((messages, size))) => {
let messages: Vec<String> = if ctx.disable_formatting { let messages: Vec<String> = if ctx.disable_formatting {
messages messages
} else { } else {
messages.into_iter().flat_map(|o| format_message(ctx.clone(), o)).collect() messages.into_iter().flat_map(|o| format_message(ctx.clone(), o)).collect()
}; };
ctx.messages.update(messages.clone(), size);
print_console(ctx.clone(), messages, &ctx.input.read().unwrap())?; if ctx.enable_chunked {
ctx.messages.append(messages.clone(), size);
print_console(ctx.clone(), ctx.messages.messages(), &ctx.input.read().unwrap())?;
} else {
ctx.messages.update(messages.clone(), size);
print_console(ctx.clone(), messages, &ctx.input.read().unwrap())?;
}
} }
Err(e) => { Err(e) => {
println!("{:?}", e); println!("{:?}", e);

View File

@ -33,6 +33,8 @@ pub struct Config {
pub enable_auth: bool, pub enable_auth: bool,
#[serde(default)] #[serde(default)]
pub enable_ssl: bool, pub enable_ssl: bool,
#[serde(default)]
pub enable_chunked: bool,
} }
fn default_max_messages() -> usize { 200 } fn default_max_messages() -> usize { 200 }
@ -75,6 +77,7 @@ pub fn configure(path: PathBuf) -> Config {
let disable_ip_hiding = ask_bool("Enable your IP viewing?", false); let disable_ip_hiding = ask_bool("Enable your IP viewing?", false);
let enable_auth = ask_bool("Enable auth-mode?", false); let enable_auth = ask_bool("Enable auth-mode?", false);
let enable_ssl = ask_bool("Enable SSL?", false); let enable_ssl = ask_bool("Enable SSL?", false);
let enable_chunked = ask_bool("Enable chunked reading?", false);
let config = Config { let config = Config {
host, host,
@ -85,7 +88,8 @@ pub fn configure(path: PathBuf) -> Config {
enable_ip_viewing, enable_ip_viewing,
disable_ip_hiding, disable_ip_hiding,
enable_auth, enable_auth,
enable_ssl enable_ssl,
enable_chunked
}; };
let config_text = serde_yml::to_string(&config).expect("Config save error"); let config_text = serde_yml::to_string(&config).expect("Config save error");
@ -188,6 +192,10 @@ pub struct Args {
/// Enable SSL /// Enable SSL
#[arg(short='S', long)] #[arg(short='S', long)]
pub enable_ssl: bool, pub enable_ssl: bool,
/// Enable chunked reading
#[arg(short='u', long)]
pub enable_chunked: bool,
} }
pub struct Context { pub struct Context {
@ -205,6 +213,7 @@ pub struct Context {
pub scroll: Arc<AtomicUsize>, pub scroll: Arc<AtomicUsize>,
pub enable_auth: bool, pub enable_auth: bool,
pub enable_ssl: bool, pub enable_ssl: bool,
pub enable_chunked: bool,
} }
impl Context { impl Context {
@ -223,7 +232,8 @@ impl Context {
enable_ip_viewing: args.enable_users_ip_viewing || config.enable_ip_viewing, enable_ip_viewing: args.enable_users_ip_viewing || config.enable_ip_viewing,
scroll: Arc::new(AtomicUsize::new(0)), scroll: Arc::new(AtomicUsize::new(0)),
enable_auth: args.enable_auth || config.enable_auth, enable_auth: args.enable_auth || config.enable_auth,
enable_ssl: args.enable_ssl || config.enable_ssl enable_ssl: args.enable_ssl || config.enable_ssl,
enable_chunked: args.enable_chunked || config.enable_chunked,
} }
} }
} }

View File

@ -52,7 +52,8 @@ fn main() {
&mut stream, &mut stream,
ctx.max_messages, ctx.max_messages,
0, 0,
!ctx.enable_ssl !ctx.enable_ssl,
false
) )
.ok().flatten() .ok().flatten()
.expect("Error reading messages").0.join("\n") .expect("Error reading messages").0.join("\n")

View File

@ -66,11 +66,17 @@ fn skip_null(stream: &mut impl Read) -> Result<Vec<u8>, Box<dyn Error>> {
} }
} }
pub fn read_messages(stream: &mut (impl Read + Write), max_messages: usize, last_size: usize, skip_null_: bool) -> Result<Option<(Vec<String>, usize)>, Box<dyn Error>> { pub fn read_messages(
stream: &mut (impl Read + Write),
max_messages: usize,
last_size: usize,
start_null: bool,
chunked: bool
) -> Result<Option<(Vec<String>, usize)>, Box<dyn Error>> {
stream.write_all(&[0x00])?; stream.write_all(&[0x00])?;
let packet_size = { let packet_size = {
let data = if skip_null_ { let data = if start_null {
let mut data = skip_null(stream)?; let mut data = skip_null(stream)?;
loop { loop {
@ -99,20 +105,25 @@ pub fn read_messages(stream: &mut (impl Read + Write), max_messages: usize, last
return Ok(None); return Ok(None);
} }
stream.write_all(&[0x01])?; let to_read = if !chunked || last_size == 0 {
stream.write_all(&[0x01])?;
packet_size
} else {
stream.write_all(format!("\x02{}", last_size).as_bytes())?;
packet_size - last_size
};
let packet_data = { let packet_data = {
let data = if skip_null_ { let data = if start_null {
let mut data = skip_null(stream)?; let mut data = skip_null(stream)?;
while data.len() < packet_size { while data.len() < to_read {
let mut buf = vec![0; packet_size - data.len()]; let mut buf = vec![0; to_read - data.len()];
let read_bytes = stream.read(&mut buf)?; stream.read_exact(&mut buf)?;
buf.truncate(read_bytes);
data.append(&mut buf); data.append(&mut buf);
} }
data data
} else { } else {
let mut data = vec![0; packet_size]; let mut data = vec![0; to_read];
stream.read_exact(&mut data)?; stream.read_exact(&mut data)?;
data data
}; };