diff --git a/src/apps/chat.rs b/src/apps/chat.rs index a3105ee..a9572e8 100644 --- a/src/apps/chat.rs +++ b/src/apps/chat.rs @@ -1,6 +1,8 @@ use core::fmt::Write; +use dhcparse::dhcpv4::MAX_MESSAGE_SIZE; use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, mutex::Mutex}; use heapless::{String, Vec}; +use log::info; use percent_encoding::percent_decode_str; use pico_website::unwrap; use ringbuffer::{ConstGenericRingBuffer, RingBuffer}; @@ -44,7 +46,7 @@ impl App for ChatApp { let (path, args) = path.split_once('?').unwrap_or((path, "")); let mut load = None; let mut username = None; - // let mut msg_content = None; + let mut msg_content = None; for arg in args.split('&').chain(content.split('&')) { match arg.split_once('=') { Some(("load", n)) => { @@ -57,49 +59,76 @@ impl App for ChatApp { } } Some(("username", u)) => { - if u.len() < USERNAME_MIN_SIZE || u.len() > USERNAME_SIZE { + let mut name = String::::new(); + for c in percent_decode_str(u) { + if let Err(_) = name.push(c as char) { + return (HttpResCode::BadRequest, "", &[]); + } + } + if u.len() < USERNAME_MIN_SIZE { return (HttpResCode::BadRequest, "", &[]); } - username = Some(u); + username = Some(name); } Some(("msg", m)) => { let mut msg = String::::new(); for c in percent_decode_str(m) { - msg.push(c as char); + if let Err(_) = msg.push(c as char) { + return (HttpResCode::BadRequest, "", &[]); + } } - if m.len() > MSG_SIZE { - return (HttpResCode::BadRequest, "", &[]); - } - // msg_content = Some(); + msg_content = Some(msg); } _ => {} } } + info!( + "load:{:?} | username:{:?} | msg:{:?}", + load, username, msg_content + ); if path == "/chat/connect" && username.is_some() { self.res_buf.clear(); unwrap(write!( &mut self.res_buf, - "
", + " +
\ +
\ +
\ + ", + username.unwrap(), MEMORY_SIZE, - username.unwrap() + MAX_MESSAGE_SIZE )) .await; return (HttpResCode::Ok, "html", &self.res_buf); - } else if path == "/chat/send" && username.is_some() { - return (HttpResCode::Ok, "html", &self.res_buf); - } else if path.starts_with("/chat/message/abs/") && path.len() > 18 { - let msg_id: u16 = match path[18..].parse() { + } else if path == "/chat/send" && username.is_some() && msg_content.is_some() { + let mut msgs = MESSAGES.lock().await; + msgs.push(Message { + author: username.unwrap(), + content: msg_content.unwrap(), + }); + return (HttpResCode::NoContent, "", &[]); + } else if path.starts_with("/chat/message/") && path.len() > 14 { + let msg_id: u16 = match path[14..].parse() { Ok(n) => n, Err(_) => return (HttpResCode::BadRequest, "", &[]), }; let msgs = MESSAGES.lock().await; - if msg_id >= msgs.next { + if msg_id > msgs.next { return (HttpResCode::BadRequest, "", &[]); } if msg_id < msgs.next.saturating_sub(MEMORY_SIZE as u16 + 1) { @@ -107,28 +136,49 @@ impl App for ChatApp { } self.res_buf.clear(); unwrap(write!(&mut self.res_buf, "
msg, + None => return (HttpResCode::NoContent, "", &[]), + }; + unwrap(write!( + &mut self.res_buf, + ">{}: {}
", + msg.author, msg.content )) .await; - } - let msg = match msgs.get_abs(msg_id) { - Some(msg) => msg, - None => return (HttpResCode::NoContent, "", &[]), }; - unwrap(write!( - &mut self.res_buf, - ">{}: {}", - msg.author, msg.content - )) - .await; + return (HttpResCode::Ok, "html", &self.res_buf); } else { (HttpResCode::NotFound, "", &[]) @@ -151,11 +201,15 @@ impl Messages { const fn new() -> Self { Self { inner: ConstGenericRingBuffer::new(), - next: 2, + next: 0, } } fn get_abs(&self, id: u16) -> Option<&Message> { - self.inner - .get_signed((id as isize) + 1 - (self.next as isize)) + self.inner.get_signed((id as isize) - (self.next as isize)) + } + fn push(&mut self, msg: Message) { + info!("{}: {}", msg.author, msg.content); + self.inner.push(msg); + self.next += 1; } }