From 8f12a03e46bfeb96f2c07855888c6929d92a0e23 Mon Sep 17 00:00:00 2001 From: maxstrb Date: Tue, 21 Oct 2025 20:16:37 +0200 Subject: [PATCH] dataframe struc definition --- src/main.rs | 11 ++++++---- src/request.rs | 18 +++++++++++++++++ src/response.rs | 12 ++++++++++- src/shared_enums.rs | 3 +++ src/websoket_connection.rs | 41 ++++++++++++++++++++++++++++++++++++-- 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index d8f6570..a1e8250 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,9 +37,10 @@ async fn handle_connection(stream: TcpStream) -> tokio::io::Result<()> { async fn handle_http_connection( mut stream: TcpStream, ) -> tokio::io::Result> { + let mut timeout = 500; loop { let req = match time::timeout( - Duration::from_millis(500), + Duration::from_millis(timeout), request::Request::from_bufreader(&mut stream), ) .await @@ -65,9 +66,9 @@ async fn handle_http_connection( } } ["websocket"] => { - return Ok(Some(WebsocketConnection::initialize_connection( - req, stream, - )?)); + return Ok(Some( + WebsocketConnection::initialize_connection(req, stream).await?, + )); } [] => Response::new() .with_code(ResponseCode::PermanentRedirect) @@ -83,6 +84,8 @@ async fn handle_http_connection( stream.flush().await?; + timeout = 5000; + if req.headers.contains(&request::RequestHeader::Connection( request::Connection::Close, )) { diff --git a/src/request.rs b/src/request.rs index 96713ee..0af0c9c 100644 --- a/src/request.rs +++ b/src/request.rs @@ -54,6 +54,15 @@ pub struct Upgrade { pub version: Box, } +impl Upgrade { + pub fn to_str(&self) -> Box { + match self.version.as_ref() { + "" => format!("{}", self.protocol.to_str()).into(), + _ => format!("{}/{}", self.protocol.to_str(), self.version).into(), + } + } +} + impl FromStr for Upgrade { type Err = tokio::io::Error; fn from_str(_s: &str) -> Result { @@ -67,6 +76,15 @@ pub enum Protocol { Websocket, } +impl Protocol { + pub fn to_str(&self) -> &'static str { + match self { + Self::HTTP => "HTTP", + Self::Websocket => "websocket", + } + } +} + impl FromStr for RequestHeader { type Err = tokio::io::Error; diff --git a/src/response.rs b/src/response.rs index 025bec4..e3d9780 100644 --- a/src/response.rs +++ b/src/response.rs @@ -1,7 +1,7 @@ use std::{ffi::OsStr, path::Path}; use crate::{ - request::{Connection, ServerPath}, + request::{Connection, ServerPath, Upgrade}, shared_enums::{Content, ContentType}, }; @@ -249,6 +249,11 @@ pub enum ResponseHeader { CacheControl(CacheControl), Connection(Connection), Location(ServerPath), + Upgrade(Upgrade), + Other { + header_name: Box, + header_value: Box, + }, } impl ResponseHeader { @@ -259,6 +264,11 @@ impl ResponseHeader { R::CacheControl(c) => format!("Cache-Control: {}", c.to_str()).into(), R::Connection(c) => format!("Connection: {}", c.to_str()).into(), R::Location(l) => format!("Location: /{}", l.path.join("/")).into(), + R::Other { + header_name, + header_value, + } => format!("{header_name}: {header_value}").into(), + R::Upgrade(upg) => format!("Upgrade: {}", upg.to_str()).into(), } } } diff --git a/src/shared_enums.rs b/src/shared_enums.rs index 12e7ccc..656c453 100644 --- a/src/shared_enums.rs +++ b/src/shared_enums.rs @@ -233,6 +233,7 @@ impl FromStr for ContentType { ["image", "webp"] => Ok(ContentType::Image(Image::Webp)), ["image", "svg"] | ["image", "svg+xml"] => Ok(ContentType::Image(Image::Svg)), ["image", "*"] => Ok(ContentType::Image(Image::Any)), + ["image", "jxl"] => Ok(ContentType::Image(Image::JpegXL)), _ => { println!("{parts:?}"); @@ -250,6 +251,7 @@ pub enum Image { Webp, Svg, Any, + JpegXL, } impl Image { @@ -260,6 +262,7 @@ impl Image { Image::Jpeg => "jpeg", Image::Webp => "webp", Image::Svg => "svg", + Image::JpegXL => "jxl", Image::Any => "*", } } diff --git a/src/websoket_connection.rs b/src/websoket_connection.rs index 3473b75..286f58e 100644 --- a/src/websoket_connection.rs +++ b/src/websoket_connection.rs @@ -1,5 +1,5 @@ use crate::{ - request::{Connection, Protocol, Request, RequestHeader}, + request::{Connection, Protocol, Request, RequestHeader, Upgrade}, response::Response, }; @@ -13,7 +13,30 @@ pub struct WebsocketConnection { stream: TcpStream, } +struct DataFrame { + is_final: bool, + extension_1: bool, + extension_2: bool, + extension_3: bool, + + frame_type: FrameType, + + is_masked: bool, + + data: Vec, +} + +enum FrameType {} + impl WebsocketConnection { + pub async fn send_message() -> io::Result<()> { + todo!() + } + + pub async fn read_next_message() { + todo!() + } + pub async fn initialize_connection( req: Request, mut stream: TcpStream, @@ -54,7 +77,21 @@ impl WebsocketConnection { let result = hasher.finalize(); let result = BASE64_STANDARD.encode(result); - Response::new().with_code(200).with_header(crate::response::ResponseHeader::Location) + Response::new() + .with_code(crate::response::ResponseCode::SwitchingProtocols) + .with_header(crate::response::ResponseHeader::Upgrade(Upgrade { + protocol: Protocol::Websocket, + version: "".into(), + })) + .with_header(crate::response::ResponseHeader::Connection( + Connection::Upgrade, + )) + .with_header(crate::response::ResponseHeader::Other { + header_name: "Sec-WebSocket-Accept".into(), + header_value: result.into(), + }) + .respond(&mut stream) + .await?; Ok(Self { stream }) } else {