initial commit
This commit is contained in:
111
src/main.rs
Normal file
111
src/main.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user