From 40ccfa01d6ec0d0febc4dce0d39e14c7244be6d1 Mon Sep 17 00:00:00 2001 From: maxstrb Date: Mon, 13 Oct 2025 21:36:52 +0200 Subject: [PATCH] firefox communication --- src/main.rs | 39 +++++++++++++++++++++++---------- src/request.rs | 53 ++++++++++++++++++++++++++++++++++++++++----- src/shared_enums.rs | 15 +++++++------ 3 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/main.rs b/src/main.rs index 77c2b4c..7ff2561 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,34 +5,49 @@ mod shared_enums; use std::{ io::{BufReader, Write}, net::TcpListener, + time::Duration, }; use crate::{ + request::ServerPath, response::{Response, ResponseCode, ResponseHeader}, - shared_enums::Content, + shared_enums::{Content, ContentType}, }; fn main() -> std::io::Result<()> { let listener = TcpListener::bind("127.0.0.1:8080")?; for incoming_stream in listener.incoming() { - let stream = incoming_stream?; + let mut stream = incoming_stream?; + stream.set_read_timeout(Some(Duration::from_millis(500)))?; - let reader = BufReader::new(&stream); + loop { + let reader = BufReader::new(&stream); + let req = match request::Request::from_bufreader(reader) { + Ok(r) => r, + Err(_) => break, + }; - let req = request::Request::from_bufreader(reader)?; + println!("{req:?}"); - println!("{req:?}"); + let response = match req.path.path.to_string().as_str(){ + "css.css" => Response::new().with_code(ResponseCode::Ok).with_data(b"body{background-color: #000000;}".to_vec()).with_header(ResponseHeader::ContentType(Content::new(ContentType::Text(shared_enums::TextType::Css)))), - let mut writer = stream; - - let response = Response::new() + _ => Response::new() .with_code(ResponseCode::Ok) - .with_data(b"Hello World!

Ahojky

Jou jou jou

".to_vec()) - .with_header(ResponseHeader::ContentType(Content::html_utf8())); + .with_data(b"Hello World!

Ahojky

Jou jou jou

".to_vec()) + .with_header(ResponseHeader::ContentType(Content::html_utf8())), + }; - response.respond(&mut writer)?; + response.respond(&mut stream)?; - writer.flush()?; + stream.flush()?; + + if req.headers.contains(&request::RequestHeader::Connection( + request::Connection::Close, + )) { + break; + } + } } Ok(()) } diff --git a/src/request.rs b/src/request.rs index a7cb462..43bcabb 100644 --- a/src/request.rs +++ b/src/request.rs @@ -19,13 +19,42 @@ pub struct Request { pub body: Option>, } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum RequestHeader { Host(String), UserAgent(String), ContentType(Content), Accept(Vec), - Other(Box, Box), + Connection(Connection), + Upgrade(Vec), + Other { name: Box, value: Box }, +} + +#[derive(Debug, PartialEq)] +pub enum Connection { + Close, + KeepAlive, + Upgrade, + Other(Box), +} + +#[derive(Debug, PartialEq)] +pub struct Upgrade { + protocol: Protocol, + version: Box, +} + +impl FromStr for Upgrade { + type Err = io::Error; + fn from_str(s: &str) -> Result { + todo!() + } +} + +#[derive(Debug, PartialEq)] +pub enum Protocol { + HTTP, + Websocket, } impl FromStr for RequestHeader { @@ -45,10 +74,22 @@ impl FromStr for RequestHeader { .map(Content::from_str) .collect::, io::Error>>()?, )), - _ => Ok(RequestHeader::Other( - header_type.to_string().into_boxed_str(), - value.to_string().into_boxed_str(), + "Connection" => Ok(RequestHeader::Connection(match *value { + "close" => Connection::Close, + "keep-alive" => Connection::KeepAlive, + "Upgrade" => Connection::Upgrade, + other => Connection::Other(other.to_string().into_boxed_str()), + })), + "Upgrade" => Ok(RequestHeader::Upgrade( + value + .split(',') + .map(Upgrade::from_str) + .collect::, io::Error>>()?, )), + _ => Ok(RequestHeader::Other { + name: header_type.to_string().into_boxed_str(), + value: value.to_string().into_boxed_str(), + }), }, _ => Err(io::Error::new( io::ErrorKind::InvalidData, @@ -81,7 +122,7 @@ impl Request { let header = RequestHeader::from_str(¤t_line)?; headers.push(header); - if let RequestHeader::Other(_, _) = headers.last().unwrap() { + if let RequestHeader::Other { .. } = headers.last().unwrap() { continue; } diff --git a/src/shared_enums.rs b/src/shared_enums.rs index 78ca4ea..aa58948 100644 --- a/src/shared_enums.rs +++ b/src/shared_enums.rs @@ -1,6 +1,6 @@ use std::{io, str::FromStr}; -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum ContentType { Text(TextType), Aplication(ApplicationType), @@ -21,7 +21,7 @@ impl ContentType { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Parameter { Preference(f32), Charset(Charset), @@ -38,7 +38,7 @@ impl Parameter { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Charset { UTF8, } @@ -51,7 +51,7 @@ impl Charset { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct Content { pub content_type: ContentType, pub parameter: Option>, @@ -232,6 +232,7 @@ impl FromStr for ContentType { ["application", "*"] => Ok(ContentType::Aplication(ApplicationType::Any)), ["image", "png"] => Ok(ContentType::Image(Image::Png)), + ["image", "apng"] => Ok(ContentType::Image(Image::Png)), ["image", "jpeg"] | ["image", "jpg"] => Ok(ContentType::Image(Image::Jpeg)), ["image", "avif"] => Ok(ContentType::Image(Image::Avif)), ["image", "webp"] => Ok(ContentType::Image(Image::Webp)), @@ -246,7 +247,7 @@ impl FromStr for ContentType { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Image { Png, Avif, @@ -269,7 +270,7 @@ impl Image { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum TextType { Html, Css, @@ -288,7 +289,7 @@ impl TextType { } } -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum ApplicationType { Json, Any,