forked from lavina/lavina
1
0
Fork 0

Compare commits

..

No commits in common. "16844f5b8568a6f0b020276d0aefcd36bc4d12c4" and "887fd95194fb9e1ea1ab72069b71ca7f1d68dfec" have entirely different histories.

5 changed files with 39 additions and 134 deletions

View File

@ -7,7 +7,6 @@ use nonempty::nonempty;
use nonempty::NonEmpty; use nonempty::NonEmpty;
use prometheus::{IntCounter, IntGauge, Registry as MetricsRegistry}; use prometheus::{IntCounter, IntGauge, Registry as MetricsRegistry};
use serde::Deserialize; use serde::Deserialize;
use tokio::io::AsyncReadExt;
use tokio::io::{AsyncBufReadExt, AsyncWrite, AsyncWriteExt, BufReader, BufWriter}; use tokio::io::{AsyncBufReadExt, AsyncWrite, AsyncWriteExt, BufReader, BufWriter};
use tokio::net::tcp::{ReadHalf, WriteHalf}; use tokio::net::tcp::{ReadHalf, WriteHalf};
use tokio::net::{TcpListener, TcpStream}; use tokio::net::{TcpListener, TcpStream};
@ -97,7 +96,7 @@ async fn handle_registration<'a>(
let mut pass: Option<Str> = None; let mut pass: Option<Str> = None;
let user = loop { let user = loop {
let res = read_irc_message(reader, &mut buffer).await; let res = reader.read_until(b'\n', &mut buffer).await;
let res = match res { let res = match res {
Ok(len) => { Ok(len) => {
if len == 0 { if len == 0 {
@ -253,7 +252,7 @@ async fn handle_registered_socket<'a>(
loop { loop {
select! { select! {
biased; biased;
len = read_irc_message(reader, &mut buffer) => { len = reader.read_until(b'\n', &mut buffer) => {
let len = len?; let len = len?;
let len = if len == 0 { let len = if len == 0 {
log::info!("EOF, Terminating socket"); log::info!("EOF, Terminating socket");
@ -292,21 +291,6 @@ async fn handle_registered_socket<'a>(
Ok(()) Ok(())
} }
async fn read_irc_message(reader: &mut BufReader<ReadHalf<'_>>, buf: &mut Vec<u8>) -> Result<usize> {
let mut size = 0;
'outer: loop {
let res = reader.read_until(b'\r', buf).await?;
size += res;
let next = reader.read_u8().await?;
buf.push(next);
size += 1;
if next != b'\n' {
continue 'outer;
}
return Ok(size);
}
}
async fn handle_update( async fn handle_update(
config: &ServerConfig, config: &ServerConfig,
user: &RegisteredUser, user: &RegisteredUser,

View File

@ -1,6 +1,6 @@
use super::*; use super::*;
use nom::combinator::{all_consuming, opt}; use nom::combinator::opt;
/// Client-to-server command. /// Client-to-server command.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -60,8 +60,8 @@ pub enum ClientMessage {
}, },
} }
pub fn client_message(input: &str) -> Result<ClientMessage, anyhow::Error> { pub fn client_message(input: &str) -> IResult<&str, ClientMessage> {
let (_, m) = all_consuming(alt(( alt((
client_message_capability, client_message_capability,
client_message_ping, client_message_ping,
client_message_pong, client_message_pong,
@ -75,8 +75,7 @@ pub fn client_message(input: &str) -> Result<ClientMessage, anyhow::Error> {
client_message_part, client_message_part,
client_message_privmsg, client_message_privmsg,
client_message_quit, client_message_quit,
)))(input)?; ))(input)
Ok(m)
} }
fn client_message_capability(input: &str) -> IResult<&str, ClientMessage> { fn client_message_capability(input: &str) -> IResult<&str, ClientMessage> {
@ -90,14 +89,24 @@ fn client_message_ping(input: &str) -> IResult<&str, ClientMessage> {
let (input, _) = tag("PING ")(input)?; let (input, _) = tag("PING ")(input)?;
let (input, token) = token(input)?; let (input, token) = token(input)?;
Ok((input, ClientMessage::Ping { token: token.into() })) Ok((
input,
ClientMessage::Ping {
token: token.into(),
},
))
} }
fn client_message_pong(input: &str) -> IResult<&str, ClientMessage> { fn client_message_pong(input: &str) -> IResult<&str, ClientMessage> {
let (input, _) = tag("PONG ")(input)?; let (input, _) = tag("PONG ")(input)?;
let (input, token) = token(input)?; let (input, token) = token(input)?;
Ok((input, ClientMessage::Pong { token: token.into() })) Ok((
input,
ClientMessage::Pong {
token: token.into(),
},
))
} }
fn client_message_nick(input: &str) -> IResult<&str, ClientMessage> { fn client_message_nick(input: &str) -> IResult<&str, ClientMessage> {
@ -216,7 +225,12 @@ fn client_message_quit(input: &str) -> IResult<&str, ClientMessage> {
let (input, _) = tag("QUIT :")(input)?; let (input, _) = tag("QUIT :")(input)?;
let (input, reason) = token(input)?; let (input, reason) = token(input)?;
Ok((input, ClientMessage::Quit { reason: reason.into() })) Ok((
input,
ClientMessage::Quit {
reason: reason.into(),
},
))
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -278,7 +292,9 @@ mod test {
#[test] #[test]
fn test_client_message_ping() { fn test_client_message_ping() {
let input = "PING 1337"; let input = "PING 1337";
let expected = ClientMessage::Ping { token: "1337".into() }; let expected = ClientMessage::Ping {
token: "1337".into(),
};
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result)); assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));
@ -286,7 +302,9 @@ mod test {
#[test] #[test]
fn test_client_message_pong() { fn test_client_message_pong() {
let input = "PONG 1337"; let input = "PONG 1337";
let expected = ClientMessage::Pong { token: "1337".into() }; let expected = ClientMessage::Pong {
token: "1337".into(),
};
let result = client_message(input); let result = client_message(input);
assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result)); assert_matches!(result, Ok((_, result)) => assert_eq!(expected, result));

View File

@ -104,7 +104,7 @@ mod test {
use assert_matches::*; use assert_matches::*;
use super::*; use super::*;
use crate::{testkit::*, client::client_message}; use crate::testkit::*;
#[test] #[test]
fn test_chan_global() { fn test_chan_global() {
@ -153,10 +153,4 @@ mod test {
assert_eq!(bytes.as_slice(), input.as_bytes()); assert_eq!(bytes.as_slice(), input.as_bytes());
} }
#[test]
fn test_aa() {
dbg!(client_message("PING asd"));
panic!()
}
} }

View File

@ -1,10 +1,8 @@
#![allow(unused_variables)]
use quick_xml::events::Event; use quick_xml::events::Event;
use quick_xml::name::ResolveResult; use quick_xml::name::ResolveResult;
use crate::xml::*;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use crate::xml::*;
pub const XMLNS: &'static str = "http://jabber.org/protocol/muc"; pub const XMLNS: &'static str = "http://jabber.org/protocol/muc";
@ -22,8 +20,8 @@ impl FromXml for History {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> { |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let mut history = History::default(); let mut history = History::default();
let (bytes, end) = match event { let (bytes, end) = match event {
Event::Start(bytes) if bytes.name().0 == Self::NAME.as_bytes() => (bytes, false), Event::Start(bytes) => (bytes, false),
Event::Empty(bytes) if bytes.name().0 == Self::NAME.as_bytes() => (bytes, true), Event::Empty(bytes) => (bytes, true),
_ => return Err(anyhow!("Unexpected XML event: {event:?}")), _ => return Err(anyhow!("Unexpected XML event: {event:?}")),
}; };
for attr in bytes.attributes() { for attr in bytes.attributes() {
@ -74,16 +72,14 @@ impl FromXml for Password {
fn parse() -> Self::P { fn parse() -> Self::P {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> { |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let bytes = match event { let Event::Start(bytes) = event else {
Event::Start(bytes) if bytes.name().0 == Self::NAME.as_bytes() => bytes, return Err(anyhow!("Unexpected XML event: {event:?}"));
_ => return Err(anyhow!("Unexpected XML event: {event:?}")),
}; };
let (namespace, event) = yield; let (namespace, event) = yield;
let Event::Text(bytes) = event else { let Event::Text(bytes) = event else {
return Err(anyhow!("Unexpected XML event: {event:?}")); return Err(anyhow!("Unexpected XML event: {event:?}"));
}; };
let s = std::str::from_utf8(bytes)?.to_string(); let s = std::str::from_utf8(bytes)?.to_string();
let (namespace, event) = yield;
let Event::End(bytes) = event else { let Event::End(bytes) = event else {
return Err(anyhow!("Unexpected XML event: {event:?}")); return Err(anyhow!("Unexpected XML event: {event:?}"));
}; };
@ -110,7 +106,7 @@ impl FromXml for X {
fn parse() -> Self::P { fn parse() -> Self::P {
|(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> { |(namespace, event): (ResolveResult<'static>, &'static Event<'static>)| -> Result<Self> {
let mut res = X::default(); let mut res = X::default();
let (_, end) = match event { let (bytes, end) = match event {
Event::Start(bytes) => (bytes, false), Event::Start(bytes) => (bytes, false),
Event::Empty(bytes) => (bytes, true), Event::Empty(bytes) => (bytes, true),
_ => return Err(anyhow!("Unexpected XML event: {event:?}")), _ => return Err(anyhow!("Unexpected XML event: {event:?}")),
@ -142,90 +138,3 @@ impl FromXml for X {
} }
} }
} }
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_history_success_empty() {
let input = "<history/>";
let res: History = parse(input).unwrap();
let expected = History {
maxchars: None,
maxstanzas: None,
seconds: None,
};
assert_eq!(res, expected);
}
#[test]
fn test_history_success_empty_attrs() {
let input = r#"<history maxchars="1" maxstanzas="2" seconds="4"/>"#;
let res: History = parse(input).unwrap();
let expected = History {
maxchars: Some(1),
maxstanzas: Some(2),
seconds: Some(4),
};
assert_eq!(res, expected);
}
#[test]
fn test_history_success_start_end() {
let input = r#"<history></history>"#;
let res: History = parse(input).unwrap();
let expected = History {
maxchars: None,
maxstanzas: None,
seconds: None,
};
assert_eq!(res, expected);
}
#[test]
fn test_history_incorrect_empty() {
let input = r#"<iq/>"#;
parse::<History>(input).err().unwrap();
}
#[test]
fn test_password_success() {
let input = "<password>olala</password>";
let res: Password = parse(input).unwrap();
let expected = Password("olala".into());
assert_eq!(res, expected);
}
#[test]
fn test_password_incorrect() {
let input = r#"<iq>asdsd</iq>"#;
parse::<Password>(input).err().unwrap();
}
#[test]
fn test_x_success_empty() {
let input = "<x/>";
let res: X = parse(input).unwrap();
let expected = X {
history: None,
password: None,
};
assert_eq!(res, expected);
}
#[test]
fn test_x_success_full() {
let input = r#"<x><password>ololo</password><history maxchars="1"/></x>"#;
let res: X = parse(input).unwrap();
let expected = X {
history: Some(History {
maxchars: Some(1),
maxstanzas: None,
seconds: None,
}),
password: Some(Password("ololo".into())),
};
assert_eq!(res, expected);
}
}

View File

@ -17,7 +17,7 @@ impl Parser for IgnoreParser {
fn consume<'a>( fn consume<'a>(
self: Self, self: Self,
_: ResolveResult, namespace: ResolveResult,
event: &Event<'a>, event: &Event<'a>,
) -> Continuation<Self, Self::Output> { ) -> Continuation<Self, Self::Output> {
match self.0 { match self.0 {
@ -58,5 +58,5 @@ impl FromXml for Ignore {
} }
impl ToXml for () { impl ToXml for () {
fn serialize(&self, _: &mut Vec<Event<'static>>) {} fn serialize(&self, events: &mut Vec<Event<'static>>) {}
} }