initial commit

This commit is contained in:
2023-06-11 17:20:51 -06:00
commit d906bea781
6 changed files with 1074 additions and 0 deletions

111
src/main.rs Normal file
View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2023 Emma Tebibyte
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
use std::{
io::Read,
net::{ TcpListener, TcpStream },
thread,
};
use serde_derive::Deserialize;
#[derive(Debug, Deserialize)]
struct MessageOuter {
auth: Option<String>,
message: Message,
to: String,
}
#[derive(Debug, Deserialize)]
struct Message {
body: String,
from: Option<String>,
}
fn parse_message(input: &str) -> MessageOuter {
let mut auth: Option<String> = None;
let mut body = String::new();
let mut from = None;
let mut to = String::new();
for line in input.lines() {
let mut parts = line.split_whitespace();
if let Some(field) = parts.next() {
if let Some(value) = parts.next() {
match field {
"AUTH" => auth = Some(value.to_string()),
"BODY" => body = value.to_string(),
"FROM" => from = Some(value.to_string()),
"TO" => to = value.to_string(),
_ => {},
}
}
}
}
let message_inner = Message {
body,
from,
};
let message_outer = MessageOuter {
auth,
message: message_inner,
to,
};
message_outer
}
fn handle_client(mut stream: TcpStream) {
let mut buffer = [0; 1024];
while let Ok(bytes_read) = stream.read(&mut buffer) {
if bytes_read == 0 { break }
let message_outer = parse_message(
String::from_utf8_lossy(&buffer[..bytes_read]).as_ref()
);
let user = match message_outer.message.from {
Some(user) => user,
None => format!("anon"),
};
println!("{}: {}", user, message_outer.message.body);
}
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:8080")
.expect("Failed to bind address");
println!("Server listening on 127.0.0.1:8080");
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move || {
handle_client(stream);
});
}
Err(err) => {
eprintln!("Error accepting client connection: {}", err);
}
}
}
}